From a249286f6a94f07e3cb9847d3be500d5359fd3eb Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Sun, 17 Mar 2024 16:42:32 +0200 Subject: [PATCH 01/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 {src => Source}/configure/test/index.ts | 0 {src => Source}/configure/test/runTest.ts | 0 .../configure/test/suite/GitHubClient.test.ts | 0 .../configure/test/suite/commonHelper.test.ts | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 301 +- 131 files changed, 139 insertions(+), 8860 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/test/index.ts (100%) rename {src => Source}/configure/test/runTest.ts (100%) rename {src => Source}/configure/test/suite/GitHubClient.test.ts (100%) rename {src => Source}/configure/test/suite/commonHelper.test.ts (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/test/index.ts b/Source/configure/test/index.ts similarity index 100% rename from src/configure/test/index.ts rename to Source/configure/test/index.ts diff --git a/src/configure/test/runTest.ts b/Source/configure/test/runTest.ts similarity index 100% rename from src/configure/test/runTest.ts rename to Source/configure/test/runTest.ts diff --git a/src/configure/test/suite/GitHubClient.test.ts b/Source/configure/test/suite/GitHubClient.test.ts similarity index 100% rename from src/configure/test/suite/GitHubClient.test.ts rename to Source/configure/test/suite/GitHubClient.test.ts diff --git a/src/configure/test/suite/commonHelper.test.ts b/Source/configure/test/suite/commonHelper.test.ts similarity index 100% rename from src/configure/test/suite/commonHelper.test.ts rename to Source/configure/test/suite/commonHelper.test.ts diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..8f638a22 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,145 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "version": "1.2.3", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", + "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/vscode-deploy-azure" + }, + "license": "MIT", + "publisher": "ms-vscode-deploy-azure", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } + "languages": [ + { + "aliases": [ + "YAML", + "yaml" ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "azure-arm-resource": "7.3.0", + "azure-arm-website": "5.7.0", + "azureintegration-repoanalysis-client-internal": "^1.0.0", + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "vscode-azureextensionui": "0.26.3", + "vscode-extension-telemetry": "0.0.18", + "vscode-languageclient": "^5.2.1", + "vscode-nls": "3.2.4", + "vscode-uri": "1.0.6", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mocha": "^7.0.2", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "mocha": "^7.1.2", + "nock": "^13.0.2", + "ts-node": "7.0.1", + "tslint-microsoft-contrib": "^6.2.0", + "typescript": "3.3.1", + "typescript-tslint-plugin": "^0.5.5", + "vscode": "1.1.37", + "vscode-azureextensiondev": "^0.3.1", + "vscode-test": "^1.3.0" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} From 134754f9f471ec86fb440d2aae735eda65f8d9fd Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Sun, 17 Mar 2024 21:59:01 +0200 Subject: [PATCH 02/96] squash! --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 8f638a22..1acf45eb 100644 --- a/package.json +++ b/package.json @@ -90,48 +90,48 @@ "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", + "azureintegration-repoanalysis-client-internal": "1.0.0", + "fs-extra": "9.0.1", + "js-yaml": "3.13.1", + "jsonpath-plus": "3.0.0", "mustache": "3.0.1", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.3.2", + "shelljs": "0.3.0", + "simple-git": "1.110.0", "tweetsodium": "0.0.4", "typed-rest-client": "1.0.7", "underscore": "1.9.1", - "uuid": "^3.3.2", + "uuid": "3.3.2", "vscode-azureextensionui": "0.26.3", "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", + "vscode-languageclient": "5.2.1", "vscode-nls": "3.2.4", "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" + "yaml-language-server": "0.8.0" }, "devDependencies": { "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", + "@types/glob": "7.1.1", + "@types/js-yaml": "3.12.1", + "@types/mocha": "7.0.2", "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", + "@types/node": "7.0.43", "@types/q": "1.5.0", "@types/underscore": "1.8.9", - "ajv": "^6.9.1", + "ajv": "6.9.1", "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", + "chai": "4.2.0", + "glob": "7.1.6", + "mocha": "7.1.2", + "nock": "13.0.2", "ts-node": "7.0.1", - "tslint-microsoft-contrib": "^6.2.0", + "tslint-microsoft-contrib": "6.2.0", "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", + "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" + "vscode-azureextensiondev": "0.3.1", + "vscode-test": "1.3.0" }, "extensionDependencies": [ "ms-vscode.azure-account" From e035df1fcccaa59e58ad04bd1d2bfeea715018f0 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Mon, 18 Mar 2024 14:32:15 +0200 Subject: [PATCH 03/96] squash! --- package.json | 301 +++++++++++++++++++++++++++------------------------ 1 file changed, 162 insertions(+), 139 deletions(-) diff --git a/package.json b/package.json index 1acf45eb..9d4182a2 100644 --- a/package.json +++ b/package.json @@ -1,145 +1,168 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "version": "1.2.3", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "license": "MIT", - "publisher": "ms-vscode-deploy-azure", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js", - "postinstall": "node ./node_modules/vscode/bin/install", - "vscode:prepublish": "npm run compile", - "watch": "node copyStaticFiles.js && tsc -watch -p ./" - }, - "contributes": { - "commands": [ - { - "category": "Deploy to Azure", - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline" - }, - { - "category": "Deploy to Azure", - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline" - } - ], - "configuration": { - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", - "type": "boolean" - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "default": true, - "description": "Use GitHub for creating new repository", - "type": "boolean" - } - }, - "title": "Deploy to Azure" + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "version": "1.2.3", + "publisher": "ms-vscode-deploy-azure", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/vscode-deploy-azure" + }, + "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", + "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", + "license": "MIT", + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" }, - "grammars": [ - { - "language": "yaml", - "path": "./syntaxes/yaml.tmLanguage.json", - "scopeName": "source.yaml" - } + "engines": { + "vscode": "^1.32.0" + }, + "categories": [ + "Programming Languages", + "Formatters", + "Azure" + ], + "tags": [ + "azure-pipelines", + "Azure Pipelines", + "Deploy to Azure", + "YAML" + ], + "keywords": [ + "YAML", + "Azure Pipelines", + "continuous integration", + "CI/CD" + ], + "activationEvents": [ + "*" ], - "languages": [ - { - "aliases": [ - "YAML", - "yaml" + "main": "./out/extension", + "contributes": { + "languages": [ + { + "id": "yaml", + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ] + } ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" + "grammars": [ + { + "language": "yaml", + "scopeName": "source.yaml", + "path": "./syntaxes/yaml.tmLanguage.json" + } ], - "id": "yaml" - } - ], - "menus": { - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ], - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" + "commands": [ + { + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline", + "category": "Deploy to Azure" + }, + { + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline", + "category": "Deploy to Azure" + } + ], + "menus": { + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ], + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ] + }, + "configuration": { + "title": "Deploy to Azure", + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "type": "boolean", + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "type": "boolean", + "default": true, + "description": "Use GitHub for creating new repository" + } + } } - ] - } - }, - "activationEvents": [ - "*" - ], - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "1.0.0", - "fs-extra": "9.0.1", - "js-yaml": "3.13.1", - "jsonpath-plus": "3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "7.3.2", - "shelljs": "0.3.0", - "simple-git": "1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "0.8.0" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "7.1.1", - "@types/js-yaml": "3.12.1", - "@types/mocha": "7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "6.9.1", - "assert": "1.4.1", - "chai": "4.2.0", - "glob": "7.1.6", - "mocha": "7.1.2", - "nock": "13.0.2", - "ts-node": "7.0.1", - "tslint-microsoft-contrib": "6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "0.3.1", - "vscode-test": "1.3.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ], - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" -} + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./ && node copyStaticFiles.js", + "watch": "node copyStaticFiles.js && tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install", + "pretest": "npm run compile", + "test": "node ./out/configure/test/runTest.js" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mocha": "^7.0.2", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "mocha": "^7.1.2", + "nock": "^13.0.2", + "ts-node": "7.0.1", + "tslint": "5.8.0", + "tslint-microsoft-contrib": "^6.2.0", + "typescript": "3.3.1", + "typescript-tslint-plugin": "^0.5.5", + "vscode": "1.1.37", + "vscode-azureextensiondev": "^0.3.1", + "vscode-test": "^1.3.0" + }, + "dependencies": { + "azure-arm-resource": "7.3.0", + "azure-arm-website": "5.7.0", + "azureintegration-repoanalysis-client-internal": "^1.0.0", + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "vscode-azureextensionui": "0.26.3", + "vscode-extension-telemetry": "0.0.18", + "vscode-languageclient": "^5.2.1", + "vscode-nls": "3.2.4", + "vscode-uri": "1.0.6", + "yaml-language-server": "^0.8.0" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ] +} \ No newline at end of file From ec5b6cc0c12d15cd8fd141b2af4052689cd5f1a0 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Mon, 18 Mar 2024 15:15:40 +0200 Subject: [PATCH 04/96] squash! --- package.json | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 9d4182a2..7adbe775 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "theme": "light" }, "engines": { - "vscode": "^1.32.0" + "vscode": "1.32.0" }, "categories": [ "Programming Languages", @@ -117,52 +117,52 @@ }, "devDependencies": { "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", + "@types/glob": "7.1.1", + "@types/js-yaml": "3.12.1", + "@types/mocha": "7.0.2", "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", + "@types/node": "7.0.43", "@types/q": "1.5.0", "@types/underscore": "1.8.9", - "ajv": "^6.9.1", + "ajv": "6.9.1", "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", + "chai": "4.2.0", + "glob": "7.1.6", + "mocha": "7.1.2", + "nock": "13.0.2", "ts-node": "7.0.1", "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", + "tslint-microsoft-contrib": "6.2.0", "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", + "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" + "vscode-azureextensiondev": "0.3.1", + "vscode-test": "1.3.0" }, "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", + "azureintegration-repoanalysis-client-internal": "1.0.0", + "fs-extra": "9.0.1", + "js-yaml": "3.13.1", + "jsonpath-plus": "3.0.0", "mustache": "3.0.1", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.3.2", + "shelljs": "0.3.0", + "simple-git": "1.110.0", "tweetsodium": "0.0.4", "typed-rest-client": "1.0.7", "underscore": "1.9.1", - "uuid": "^3.3.2", + "uuid": "3.3.2", "vscode-azureextensionui": "0.26.3", "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", + "vscode-languageclient": "5.2.1", "vscode-nls": "3.2.4", "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" + "yaml-language-server": "0.8.0" }, "extensionDependencies": [ "ms-vscode.azure-account" ] -} \ No newline at end of file +} From dc3b913514c6160f2a5b8b8fbb26340b538351e7 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Tue, 19 Mar 2024 01:05:27 +0200 Subject: [PATCH 05/96] squash! --- package.json | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 7adbe775..352acdbc 100644 --- a/package.json +++ b/package.json @@ -116,51 +116,51 @@ "test": "node ./out/configure/test/runTest.js" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "7.1.1", - "@types/js-yaml": "3.12.1", - "@types/mocha": "7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "6.9.1", - "assert": "1.4.1", - "chai": "4.2.0", - "glob": "7.1.6", - "mocha": "7.1.2", - "nock": "13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mocha": "10.0.6", + "@types/mustache": "4.2.5", + "@types/node": "20.11.28", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.12.0", + "assert": "2.1.0", + "chai": "5.1.0", + "glob": "10.3.10", + "mocha": "10.3.0", + "nock": "13.5.4", + "ts-node": "10.9.2", + "tslint": "5.20.1", "tslint-microsoft-contrib": "6.2.0", - "typescript": "3.3.1", + "typescript": "5.4.2", "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", - "vscode-azureextensiondev": "0.3.1", + "vscode-azureextensiondev": "0.10.4", "vscode-test": "1.3.0" }, "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", "azureintegration-repoanalysis-client-internal": "1.0.0", - "fs-extra": "9.0.1", - "js-yaml": "3.13.1", - "jsonpath-plus": "3.0.0", - "mustache": "3.0.1", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "8.1.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "7.3.2", - "shelljs": "0.3.0", - "simple-git": "1.110.0", + "semver": "7.6.0", + "shelljs": "0.8.5", + "simple-git": "3.23.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "3.3.2", + "typed-rest-client": "1.8.11", + "underscore": "1.13.6", + "uuid": "9.0.1", "vscode-azureextensionui": "0.26.3", "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "0.8.0" + "vscode-languageclient": "9.0.1", + "vscode-nls": "5.2.0", + "vscode-uri": "3.0.8", + "yaml-language-server": "1.14.0" }, "extensionDependencies": [ "ms-vscode.azure-account" From da4a24367958c0070409cc67a040073a4421f8d2 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Tue, 19 Mar 2024 21:25:40 +0200 Subject: [PATCH 06/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 352acdbc..ef472565 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "@types/js-yaml": "4.0.9", "@types/mocha": "10.0.6", "@types/mustache": "4.2.5", - "@types/node": "20.11.28", + "@types/node": "20.11.30", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.12.0", From 94e558c754108ba737f766915842255e23634762 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Thu, 21 Mar 2024 00:40:19 +0200 Subject: [PATCH 07/96] squash! --- package.json | 322 +++++++++++++++++++++++++-------------------------- 1 file changed, 156 insertions(+), 166 deletions(-) diff --git a/package.json b/package.json index ef472565..f864c8ee 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,158 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "11.0.4", - "@types/glob": "8.1.0", - "@types/js-yaml": "4.0.9", - "@types/mocha": "10.0.6", - "@types/mustache": "4.2.5", - "@types/node": "20.11.30", - "@types/q": "1.5.8", - "@types/underscore": "1.11.15", - "ajv": "8.12.0", - "assert": "2.1.0", - "chai": "5.1.0", - "glob": "10.3.10", - "mocha": "10.3.0", - "nock": "13.5.4", - "ts-node": "10.9.2", - "tslint": "5.20.1", - "tslint-microsoft-contrib": "6.2.0", - "typescript": "5.4.2", - "typescript-tslint-plugin": "0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "0.10.4", - "vscode-test": "1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "1.0.0", - "fs-extra": "11.2.0", - "js-yaml": "4.1.0", - "jsonpath-plus": "8.1.0", - "mustache": "4.2.0", - "q": "1.5.1", - "semver": "7.6.0", - "shelljs": "0.8.5", - "simple-git": "3.23.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.8.11", - "underscore": "1.13.6", - "uuid": "9.0.1", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "9.0.1", - "vscode-nls": "5.2.0", - "vscode-uri": "3.0.8", - "yaml-language-server": "1.14.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "version": "0.0.1", + "private": false, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "homepage": "https://github.com/CodeEditorLand/Foundation#readme", + "bugs": { + "url": "https://github.com/CodeEditorLand/Foundation/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeEditorLand/Foundation.git" + }, + "license": "SEE LICENSE IN LICENSE", + "author": { + "name": "Playform", + "email": "Hello@Playform.Cloud", + "url": "https://playform.cloud" + }, + "type": "module", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "azure-arm-resource": "7.3.0", + "azure-arm-website": "5.7.0", + "azureintegration-repoanalysis-client-internal": "1.0.0", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "8.1.0", + "mustache": "4.2.0", + "q": "1.5.1", + "semver": "7.6.0", + "shelljs": "0.8.5", + "simple-git": "3.23.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.8.11", + "underscore": "1.13.6", + "uuid": "9.0.1", + "vscode-azureextensionui": "0.26.3", + "vscode-extension-telemetry": "0.0.18", + "vscode-languageclient": "9.0.1", + "vscode-nls": "5.2.0", + "vscode-uri": "3.0.8", + "yaml-language-server": "1.14.0" + }, + "devDependencies": { + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mocha": "10.0.6", + "@types/mustache": "4.2.5", + "@types/node": "20.11.30", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.12.0", + "assert": "2.1.0", + "chai": "5.1.0", + "glob": "10.3.10", + "mocha": "10.3.0", + "nock": "13.5.4", + "ts-node": "10.9.2", + "tslint-microsoft-contrib": "6.2.0", + "typescript": "5.4.2", + "typescript-esbuild": "latest", + "typescript-tslint-plugin": "0.5.5", + "vscode": "1.1.37", + "vscode-azureextensiondev": "0.10.4", + "vscode-test": "1.3.0" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "publishConfig": { + "access": "public" + }, + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } From fcf419d362aa0ffb1841bd4b8f1e1d4d0fa55f0b Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Thu, 21 Mar 2024 19:45:51 +0200 Subject: [PATCH 08/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f864c8ee..eae69d11 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "ts-node": "10.9.2", "tslint-microsoft-contrib": "6.2.0", "typescript": "5.4.2", - "typescript-esbuild": "latest", + "typescript-esbuild": "0.4.5", "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", "vscode-azureextensiondev": "0.10.4", From 8d6f558b05545fce914d2e23ba7d70c43b39f790 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Fri, 22 Mar 2024 01:57:14 +0200 Subject: [PATCH 09/96] squash! --- package.json | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index eae69d11..3a51653a 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,15 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "version": "0.0.1", - "private": false, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "homepage": "https://github.com/CodeEditorLand/Foundation#readme", - "bugs": { - "url": "https://github.com/CodeEditorLand/Foundation/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/CodeEditorLand/Foundation.git" - }, - "license": "SEE LICENSE IN LICENSE", + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "author": { - "name": "Playform", "email": "Hello@Playform.Cloud", + "name": "Playform", "url": "https://playform.cloud" }, - "type": "module", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js", - "postinstall": "node ./node_modules/vscode/bin/install", - "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", - "vscode:prepublish": "npm run compile", - "watch": "node copyStaticFiles.js && tsc -watch -p ./" + "bugs": { + "url": "https://github.com/CodeEditorLand/Foundation/issues" }, "contributes": { "commands": [ @@ -93,9 +77,6 @@ ] } }, - "activationEvents": [ - "*" - ], "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", @@ -119,6 +100,7 @@ "vscode-uri": "3.0.8", "yaml-language-server": "1.14.0" }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -137,22 +119,40 @@ "ts-node": "10.9.2", "tslint-microsoft-contrib": "6.2.0", "typescript": "5.4.2", - "typescript-esbuild": "0.4.5", + "typescript-esbuild": "", "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", "vscode-azureextensiondev": "0.10.4", "vscode-test": "1.3.0" }, + "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "publishConfig": { - "access": "public" - }, - "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" + "homepage": "https://github.com/CodeEditorLand/Foundation#readme", + "icon": "assets/deployToAzure.png", + "license": "SEE LICENSE IN LICENSE", + "main": "./out/extension", + "name": "azure-deploy", + "private": false, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeEditorLand/Foundation.git" + }, + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" + }, + "type": "module", + "version": "0.0.1" } From 279e738582e60d0d09f846ffd15283a724656849 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Fri, 22 Mar 2024 06:37:03 +0200 Subject: [PATCH 10/96] squash! --- package.json | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 3a51653a..eae69d11 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,31 @@ { - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "version": "0.0.1", + "private": false, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "homepage": "https://github.com/CodeEditorLand/Foundation#readme", + "bugs": { + "url": "https://github.com/CodeEditorLand/Foundation/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeEditorLand/Foundation.git" + }, + "license": "SEE LICENSE IN LICENSE", "author": { - "email": "Hello@Playform.Cloud", "name": "Playform", + "email": "Hello@Playform.Cloud", "url": "https://playform.cloud" }, - "bugs": { - "url": "https://github.com/CodeEditorLand/Foundation/issues" + "type": "module", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" }, "contributes": { "commands": [ @@ -77,6 +93,9 @@ ] } }, + "activationEvents": [ + "*" + ], "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", @@ -100,7 +119,6 @@ "vscode-uri": "3.0.8", "yaml-language-server": "1.14.0" }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -119,40 +137,22 @@ "ts-node": "10.9.2", "tslint-microsoft-contrib": "6.2.0", "typescript": "5.4.2", - "typescript-esbuild": "", + "typescript-esbuild": "0.4.5", "typescript-tslint-plugin": "0.5.5", "vscode": "1.1.37", "vscode-azureextensiondev": "0.10.4", "vscode-test": "1.3.0" }, - "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "homepage": "https://github.com/CodeEditorLand/Foundation#readme", - "icon": "assets/deployToAzure.png", - "license": "SEE LICENSE IN LICENSE", - "main": "./out/extension", - "name": "azure-deploy", - "private": false, "publishConfig": { "access": "public" }, - "repository": { - "type": "git", - "url": "git+https://github.com/CodeEditorLand/Foundation.git" - }, - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js", - "postinstall": "node ./node_modules/vscode/bin/install", - "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", - "vscode:prepublish": "npm run compile", - "watch": "node copyStaticFiles.js && tsc -watch -p ./" + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" }, - "type": "module", - "version": "0.0.1" + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } From 5b99f1463bd6818e61caa84daa8634e02ca36ef3 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Sun, 24 Mar 2024 20:09:57 +0200 Subject: [PATCH 11/96] squash! --- package.json | 53 +++++++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index eae69d11..62f40f3e 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,8 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "version": "0.0.1", - "private": false, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "homepage": "https://github.com/CodeEditorLand/Foundation#readme", - "bugs": { - "url": "https://github.com/CodeEditorLand/Foundation/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/CodeEditorLand/Foundation.git" - }, - "license": "SEE LICENSE IN LICENSE", - "author": { - "name": "Playform", - "email": "Hello@Playform.Cloud", - "url": "https://playform.cloud" - }, - "type": "module", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js", - "postinstall": "node ./node_modules/vscode/bin/install", - "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", - "vscode:prepublish": "npm run compile", - "watch": "node copyStaticFiles.js && tsc -watch -p ./" - }, + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "contributes": { "commands": [ { @@ -93,9 +69,6 @@ ] } }, - "activationEvents": [ - "*" - ], "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", @@ -119,6 +92,7 @@ "vscode-uri": "3.0.8", "yaml-language-server": "1.14.0" }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -143,16 +117,23 @@ "vscode-azureextensiondev": "0.10.4", "vscode-test": "1.3.0" }, + "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "publishConfig": { - "access": "public" - }, - "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" + }, + "type": "module" } From 4270f028542bf507d1f9b2ef7b590d359757f6c2 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Sun, 24 Mar 2024 22:15:36 +0200 Subject: [PATCH 12/96] squash! --- package.json | 53 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 62f40f3e..eae69d11 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,32 @@ { - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "version": "0.0.1", + "private": false, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "homepage": "https://github.com/CodeEditorLand/Foundation#readme", + "bugs": { + "url": "https://github.com/CodeEditorLand/Foundation/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeEditorLand/Foundation.git" + }, + "license": "SEE LICENSE IN LICENSE", + "author": { + "name": "Playform", + "email": "Hello@Playform.Cloud", + "url": "https://playform.cloud" + }, + "type": "module", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js", + "postinstall": "node ./node_modules/vscode/bin/install", + "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", + "vscode:prepublish": "npm run compile", + "watch": "node copyStaticFiles.js && tsc -watch -p ./" + }, "contributes": { "commands": [ { @@ -69,6 +93,9 @@ ] } }, + "activationEvents": [ + "*" + ], "dependencies": { "azure-arm-resource": "7.3.0", "azure-arm-website": "5.7.0", @@ -92,7 +119,6 @@ "vscode-uri": "3.0.8", "yaml-language-server": "1.14.0" }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -117,23 +143,16 @@ "vscode-azureextensiondev": "0.10.4", "vscode-test": "1.3.0" }, - "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], + "publishConfig": { + "access": "public" + }, + "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "icon": "assets/deployToAzure.png", - "main": "./out/extension", - "name": "azure-deploy", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js", - "postinstall": "node ./node_modules/vscode/bin/install", - "prepublishOnly": "TypeScriptESBuild 'Source/**/*.ts'", - "vscode:prepublish": "npm run compile", - "watch": "node copyStaticFiles.js && tsc -watch -p ./" - }, - "type": "module" + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } From 9ddf287c011beca51564b433f61e1271647652de Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Wed, 1 May 2024 02:45:18 +0300 Subject: [PATCH 13/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 310 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 131 files changed, 143 insertions(+), 9128 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..20cb0f9d 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,144 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "version": "0.0.1", + "private": false, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "keywords": [ + "land" + ], + "homepage": "HTTPS://GitHub.Com/CodeEditorLand/LandDeployAzure#readme", + "bugs": { + "url": "HTTPS://GitHub.Com/CodeEditorLand/LandDeployAzure/issues" + }, + "repository": { + "type": "git", + "url": "git+HTTPS://github.com/CodeEditorLand/LandDeployAzure.git" + }, + "license": "SEE LICENSE IN LICENSE", + "author": { + "name": "🌆 — Land —", + "email": "Land@PlayForm.Cloud", + "url": "HTTPS://Land.PlayForm.Cloud" + }, + "type": "module", + "main": "./out/extension", + "scripts": { + "Document": "Document 'Source/**/*.ts'", + "compile": "tsc -p ./ && node copyStaticFiles.js", + "prepublishOnly": "Build 'Source/**/*.ts'" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@playform/build": "0.0.7", + "@playform/document": "0.0.6", + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "publishConfig": { + "access": "public" + }, + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From abe07031acece2a89004d2066af6b9feb564f686 Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Wed, 1 May 2024 05:12:36 +0300 Subject: [PATCH 14/96] squash! --- .github/dependabot.yml | 14 +++++ .github/workflows/Dependabot.yml | 45 ++++++++++++++++ .github/workflows/GitHub.yml | 57 ++++++++++++++++++++ .github/workflows/NPM.yml | 43 +++++++++++++++ .github/workflows/Node.yml | 92 ++++++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml create mode 100644 .github/workflows/GitHub.yml create mode 100644 .github/workflows/NPM.yml create mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..e6091e54 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml new file mode 100644 index 00000000..0be30bac --- /dev/null +++ b/.github/workflows/GitHub.yml @@ -0,0 +1,57 @@ +name: GitHub + +concurrency: + group: GitHub-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + issues: write + pull-requests: write + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + Assign: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + steps: + - uses: pozil/auto-assign-issue@v1.14.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: NikolaRHristov + numOfAssignee: 1 diff --git a/.github/workflows/NPM.yml b/.github/workflows/NPM.yml new file mode 100644 index 00000000..ede007f9 --- /dev/null +++ b/.github/workflows/NPM.yml @@ -0,0 +1,43 @@ +name: NPM + +concurrency: + group: NPM-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + release: + types: [created] + workflow_call: + +jobs: + Publish: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4.1.4 + + - uses: actions/setup-node@v4.0.2 + with: + node-version: "18" + registry-url: "https://registry.npmjs.org" + + - run: npm install -g npm + + - name: Publish . + continue-on-error: true + working-directory: . + run: | + npm install --include prod dev optional peer --legacy-peer-deps + npm publish --legacy-peer-deps --provenance + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml new file mode 100644 index 00000000..730ee629 --- /dev/null +++ b/.github/workflows/Node.yml @@ -0,0 +1,92 @@ +name: Node + +concurrency: + group: Node-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + push: + branches: [Current] + pull_request: + branches: [Current] + workflow_call: + +jobs: + Pre-Publish: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + strategy: + matrix: + node-version: [18, 19, 20] + + steps: + - uses: actions/checkout@v4.1.4 + + - uses: pnpm/action-setup@v3.0.0 + with: + version: 8.15.5 + run_install: | + - recursive: true + args: [ + --link-workspace-packages=true, + --lockfile-only, + --prefer-frozen-lockfile=false, + --shamefully-hoist=false, + --shared-workspace-lockfile=true, + --strict-peer-dependencies=false, + --unsafe-perm=true + ] + + - uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: ./pnpm-lock.yaml + + - run: pnpm install + working-directory: . + + - run: pnpm run prepublishOnly + working-directory: . + + - uses: actions/upload-artifact@v4.3.3 + with: + name: .-Node-${{ matrix.node-version }}-Target + path: ./Target From 966a84e576206d9443c44e75af01f7a2f003715e Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Wed, 1 May 2024 19:21:28 +0300 Subject: [PATCH 15/96] squash! --- package.json | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 20cb0f9d..b2b03390 100644 --- a/package.json +++ b/package.json @@ -98,36 +98,36 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "8.1.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.6.0", + "shelljs": "0.8.5", + "simple-git": "3.24.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "typed-rest-client": "1.8.11", + "underscore": "1.13.6", + "uuid": "9.0.1", + "yaml-language-server": "1.14.0" }, "devDependencies": { "@playform/build": "0.0.7", "@playform/document": "0.0.6", - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", - "typescript-tslint-plugin": "^0.5.5" + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "20.12.7", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.13.0", + "assert": "2.1.0", + "chai": "5.1.0", + "glob": "10.3.12", + "nock": "13.5.4", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From 9b295351537cdc87ecf141775a61cc1eba07650a Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Wed, 1 May 2024 22:52:03 +0300 Subject: [PATCH 16/96] squash! --- .github/dependabot.yml | 14 ----- .github/workflows/Dependabot.yml | 45 ---------------- .github/workflows/GitHub.yml | 57 -------------------- .github/workflows/NPM.yml | 43 --------------- .github/workflows/Node.yml | 92 -------------------------------- 5 files changed, 251 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml delete mode 100644 .github/workflows/GitHub.yml delete mode 100644 .github/workflows/NPM.yml delete mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index e6091e54..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.1.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.1.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml deleted file mode 100644 index 0be30bac..00000000 --- a/.github/workflows/GitHub.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: GitHub - -concurrency: - group: GitHub-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - issues: write - pull-requests: write - -on: - issues: - types: [opened] - pull_request: - types: [opened] - -jobs: - Assign: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - - steps: - - uses: pozil/auto-assign-issue@v1.14.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: NikolaRHristov - numOfAssignee: 1 diff --git a/.github/workflows/NPM.yml b/.github/workflows/NPM.yml deleted file mode 100644 index ede007f9..00000000 --- a/.github/workflows/NPM.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: NPM - -concurrency: - group: NPM-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - release: - types: [created] - workflow_call: - -jobs: - Publish: - runs-on: ubuntu-latest - - permissions: - contents: read - id-token: write - - steps: - - uses: actions/checkout@v4.1.4 - - - uses: actions/setup-node@v4.0.2 - with: - node-version: "18" - registry-url: "https://registry.npmjs.org" - - - run: npm install -g npm - - - name: Publish . - continue-on-error: true - working-directory: . - run: | - npm install --include prod dev optional peer --legacy-peer-deps - npm publish --legacy-peer-deps --provenance - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml deleted file mode 100644 index 730ee629..00000000 --- a/.github/workflows/Node.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Node - -concurrency: - group: Node-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - push: - branches: [Current] - pull_request: - branches: [Current] - workflow_call: - -jobs: - Pre-Publish: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - - strategy: - matrix: - node-version: [18, 19, 20] - - steps: - - uses: actions/checkout@v4.1.4 - - - uses: pnpm/action-setup@v3.0.0 - with: - version: 8.15.5 - run_install: | - - recursive: true - args: [ - --link-workspace-packages=true, - --lockfile-only, - --prefer-frozen-lockfile=false, - --shamefully-hoist=false, - --shared-workspace-lockfile=true, - --strict-peer-dependencies=false, - --unsafe-perm=true - ] - - - uses: actions/setup-node@v4.0.2 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./pnpm-lock.yaml - - - run: pnpm install - working-directory: . - - - run: pnpm run prepublishOnly - working-directory: . - - - uses: actions/upload-artifact@v4.3.3 - with: - name: .-Node-${{ matrix.node-version }}-Target - path: ./Target From 7c054b9846b8c5c72bec7c37716347dec3f31c3c Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Thu, 2 May 2024 04:22:02 +0300 Subject: [PATCH 17/96] squash! --- .github/dependabot.yml | 14 +++++ .github/workflows/Dependabot.yml | 45 ++++++++++++++++ .github/workflows/GitHub.yml | 57 ++++++++++++++++++++ .github/workflows/NPM.yml | 43 +++++++++++++++ .github/workflows/Node.yml | 92 ++++++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml create mode 100644 .github/workflows/GitHub.yml create mode 100644 .github/workflows/NPM.yml create mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..e6091e54 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml new file mode 100644 index 00000000..0be30bac --- /dev/null +++ b/.github/workflows/GitHub.yml @@ -0,0 +1,57 @@ +name: GitHub + +concurrency: + group: GitHub-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + issues: write + pull-requests: write + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + Assign: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + steps: + - uses: pozil/auto-assign-issue@v1.14.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: NikolaRHristov + numOfAssignee: 1 diff --git a/.github/workflows/NPM.yml b/.github/workflows/NPM.yml new file mode 100644 index 00000000..ede007f9 --- /dev/null +++ b/.github/workflows/NPM.yml @@ -0,0 +1,43 @@ +name: NPM + +concurrency: + group: NPM-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + release: + types: [created] + workflow_call: + +jobs: + Publish: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4.1.4 + + - uses: actions/setup-node@v4.0.2 + with: + node-version: "18" + registry-url: "https://registry.npmjs.org" + + - run: npm install -g npm + + - name: Publish . + continue-on-error: true + working-directory: . + run: | + npm install --include prod dev optional peer --legacy-peer-deps + npm publish --legacy-peer-deps --provenance + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml new file mode 100644 index 00000000..730ee629 --- /dev/null +++ b/.github/workflows/Node.yml @@ -0,0 +1,92 @@ +name: Node + +concurrency: + group: Node-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + push: + branches: [Current] + pull_request: + branches: [Current] + workflow_call: + +jobs: + Pre-Publish: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + strategy: + matrix: + node-version: [18, 19, 20] + + steps: + - uses: actions/checkout@v4.1.4 + + - uses: pnpm/action-setup@v3.0.0 + with: + version: 8.15.5 + run_install: | + - recursive: true + args: [ + --link-workspace-packages=true, + --lockfile-only, + --prefer-frozen-lockfile=false, + --shamefully-hoist=false, + --shared-workspace-lockfile=true, + --strict-peer-dependencies=false, + --unsafe-perm=true + ] + + - uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: ./pnpm-lock.yaml + + - run: pnpm install + working-directory: . + + - run: pnpm run prepublishOnly + working-directory: . + + - uses: actions/upload-artifact@v4.3.3 + with: + name: .-Node-${{ matrix.node-version }}-Target + path: ./Target From 8d772c08a80011f5ae1a8f3ee214fe9aa4b591cf Mon Sep 17 00:00:00 2001 From: "Nikola R. Hristov" Date: Fri, 3 May 2024 00:34:42 +0300 Subject: [PATCH 18/96] squash! --- Source/configure/test/index.ts | 38 ------ Source/configure/test/runTest.ts | 23 ---- .../configure/test/suite/GitHubClient.test.ts | 122 ------------------ .../configure/test/suite/commonHelper.test.ts | 80 ------------ 4 files changed, 263 deletions(-) delete mode 100644 Source/configure/test/index.ts delete mode 100644 Source/configure/test/runTest.ts delete mode 100644 Source/configure/test/suite/GitHubClient.test.ts delete mode 100644 Source/configure/test/suite/commonHelper.test.ts diff --git a/Source/configure/test/index.ts b/Source/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/Source/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/Source/configure/test/runTest.ts b/Source/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/Source/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/Source/configure/test/suite/GitHubClient.test.ts b/Source/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/Source/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/Source/configure/test/suite/commonHelper.test.ts b/Source/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/Source/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From ae2705f69b282336dc75279a7ff59a9f6ebafc19 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 6 May 2024 20:42:10 +0300 Subject: [PATCH 19/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b2b03390..5f5f5389 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "license": "SEE LICENSE IN LICENSE", "author": { - "name": "🌆 — Land —", + "name": "🌆 Land —", "email": "Land@PlayForm.Cloud", "url": "HTTPS://Land.PlayForm.Cloud" }, From 85705918efc9b4f553d3f8c6eed5fea3c49d3796 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 6 May 2024 22:34:29 +0300 Subject: [PATCH 20/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f5f5389..16ca09d3 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "20.12.7", + "@types/node": "20.12.10", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.13.0", From 29fc183496ef44bad98367dd7682196ba7ee3441 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 7 May 2024 18:13:30 +0300 Subject: [PATCH 21/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 16ca09d3..8f1cc4c8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "license": "SEE LICENSE IN LICENSE", "author": { - "name": "🌆 Land —", + "name": "🛬 Land —", "email": "Land@PlayForm.Cloud", "url": "HTTPS://Land.PlayForm.Cloud" }, From d455a5703ef3db0e6bef67ec3a1c01543445d1ca Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 17 May 2024 08:11:23 +0300 Subject: [PATCH 22/96] squash! --- .github/dependabot.yml | 14 ----- .github/workflows/Dependabot.yml | 45 ---------------- .github/workflows/GitHub.yml | 57 -------------------- .github/workflows/NPM.yml | 43 --------------- .github/workflows/Node.yml | 92 -------------------------------- package.json | 24 --------- 6 files changed, 275 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml delete mode 100644 .github/workflows/GitHub.yml delete mode 100644 .github/workflows/NPM.yml delete mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index e6091e54..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.1.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.1.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml deleted file mode 100644 index 0be30bac..00000000 --- a/.github/workflows/GitHub.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: GitHub - -concurrency: - group: GitHub-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - issues: write - pull-requests: write - -on: - issues: - types: [opened] - pull_request: - types: [opened] - -jobs: - Assign: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - - steps: - - uses: pozil/auto-assign-issue@v1.14.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: NikolaRHristov - numOfAssignee: 1 diff --git a/.github/workflows/NPM.yml b/.github/workflows/NPM.yml deleted file mode 100644 index ede007f9..00000000 --- a/.github/workflows/NPM.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: NPM - -concurrency: - group: NPM-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - release: - types: [created] - workflow_call: - -jobs: - Publish: - runs-on: ubuntu-latest - - permissions: - contents: read - id-token: write - - steps: - - uses: actions/checkout@v4.1.4 - - - uses: actions/setup-node@v4.0.2 - with: - node-version: "18" - registry-url: "https://registry.npmjs.org" - - - run: npm install -g npm - - - name: Publish . - continue-on-error: true - working-directory: . - run: | - npm install --include prod dev optional peer --legacy-peer-deps - npm publish --legacy-peer-deps --provenance - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml deleted file mode 100644 index 730ee629..00000000 --- a/.github/workflows/Node.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Node - -concurrency: - group: Node-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - push: - branches: [Current] - pull_request: - branches: [Current] - workflow_call: - -jobs: - Pre-Publish: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - - strategy: - matrix: - node-version: [18, 19, 20] - - steps: - - uses: actions/checkout@v4.1.4 - - - uses: pnpm/action-setup@v3.0.0 - with: - version: 8.15.5 - run_install: | - - recursive: true - args: [ - --link-workspace-packages=true, - --lockfile-only, - --prefer-frozen-lockfile=false, - --shamefully-hoist=false, - --shared-workspace-lockfile=true, - --strict-peer-dependencies=false, - --unsafe-perm=true - ] - - - uses: actions/setup-node@v4.0.2 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./pnpm-lock.yaml - - - run: pnpm install - working-directory: . - - - run: pnpm run prepublishOnly - working-directory: . - - - uses: actions/upload-artifact@v4.3.3 - with: - name: .-Node-${{ matrix.node-version }}-Target - path: ./Target diff --git a/package.json b/package.json index 8f1cc4c8..103edf26 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,7 @@ { "name": "azure-deploy", "displayName": "Deploy to Azure", - "version": "0.0.1", - "private": false, "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "keywords": [ - "land" - ], - "homepage": "HTTPS://GitHub.Com/CodeEditorLand/LandDeployAzure#readme", - "bugs": { - "url": "HTTPS://GitHub.Com/CodeEditorLand/LandDeployAzure/issues" - }, - "repository": { - "type": "git", - "url": "git+HTTPS://github.com/CodeEditorLand/LandDeployAzure.git" - }, - "license": "SEE LICENSE IN LICENSE", - "author": { - "name": "🛬 Land —", - "email": "Land@PlayForm.Cloud", - "url": "HTTPS://Land.PlayForm.Cloud" - }, - "type": "module", "main": "./out/extension", "scripts": { "Document": "Document 'Source/**/*.ts'", @@ -114,7 +94,6 @@ }, "devDependencies": { "@playform/build": "0.0.7", - "@playform/document": "0.0.6", "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", @@ -132,9 +111,6 @@ "extensionDependencies": [ "ms-vscode.azure-account" ], - "publishConfig": { - "access": "public" - }, "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", From 17bbda8e05270384f1f9ca6b15cfb67e466dca03 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 20 May 2024 15:26:58 +0300 Subject: [PATCH 23/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 131 files changed, 116 insertions(+), 21692 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From b053b392a7793519516e909facf638026c61c95f Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 21 May 2024 12:29:54 +0300 Subject: [PATCH 24/96] squash! --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 4e145024..f91d7dd1 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", + "fs-extra": "9.0.1", + "js-yaml": "3.13.1", + "jsonpath-plus": "3.0.0", "mustache": "3.0.1", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.3.2", + "shelljs": "0.3.0", + "simple-git": "1.110.0", "tweetsodium": "0.0.4", "typed-rest-client": "1.0.7", "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "uuid": "3.3.2", + "yaml-language-server": "0.8.0" }, "devDependencies": { "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", + "@types/glob": "7.1.1", + "@types/js-yaml": "3.12.1", "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", + "@types/node": "7.0.43", "@types/q": "1.5.0", "@types/underscore": "1.8.9", - "ajv": "^6.9.1", + "ajv": "6.9.1", "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", - "typescript-tslint-plugin": "^0.5.5" + "chai": "4.2.0", + "glob": "7.1.6", + "nock": "13.0.2", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From 3244e35192fcd41b3a8999dfbbed613462076d91 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 21 May 2024 14:06:41 +0300 Subject: [PATCH 25/96] squash! --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index f91d7dd1..e6ce494b 100644 --- a/package.json +++ b/package.json @@ -76,33 +76,33 @@ "*" ], "dependencies": { - "fs-extra": "9.0.1", - "js-yaml": "3.13.1", - "jsonpath-plus": "3.0.0", - "mustache": "3.0.1", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "7.3.2", - "shelljs": "0.3.0", - "simple-git": "1.110.0", + "semver": "7.6.2", + "shelljs": "0.8.5", + "simple-git": "3.24.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "3.3.2", - "yaml-language-server": "0.8.0" + "typed-rest-client": "1.8.11", + "underscore": "1.13.6", + "uuid": "9.0.1", + "yaml-language-server": "1.14.0" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "7.1.1", - "@types/js-yaml": "3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "6.9.1", - "assert": "1.4.1", - "chai": "4.2.0", - "glob": "7.1.6", - "nock": "13.0.2", + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "20.12.12", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.13.0", + "assert": "2.1.0", + "chai": "5.1.1", + "glob": "10.3.15", + "nock": "13.5.4", "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ From 2b63a91ce54062563cd866162b87c912dbe479da Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 23 May 2024 11:50:30 +0300 Subject: [PATCH 26/96] squash! --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 86466ec5..ec588ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ out -node_modules .vscode-test/ *.vsix .DS_Store From f951b9ecead3b14c982f7203e54e6c042794ee7f Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 23 May 2024 12:54:39 +0300 Subject: [PATCH 27/96] squash! --- .gitignore | 1 - package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ec588ed2..4e30e36a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ out .vscode-test/ *.vsix -.DS_Store diff --git a/package.json b/package.json index e6ce494b..03392110 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "ajv": "8.13.0", "assert": "2.1.0", "chai": "5.1.1", - "glob": "10.3.15", + "glob": "10.3.16", "nock": "13.5.4", "typescript-tslint-plugin": "0.5.5" }, From 30e8a18f32dc72c0a8c196e23140a2d4df343c40 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 25 May 2024 01:15:50 +0300 Subject: [PATCH 28/96] squash! --- .github/dependabot.yml | 14 ++++++ .github/workflows/Dependabot.yml | 45 +++++++++++++++++ .github/workflows/GitHub.yml | 57 ++++++++++++++++++++++ .github/workflows/Node.yml | 84 ++++++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml create mode 100644 .github/workflows/GitHub.yml create mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..e6091e54 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.1.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml new file mode 100644 index 00000000..5e814e3e --- /dev/null +++ b/.github/workflows/GitHub.yml @@ -0,0 +1,57 @@ +name: GitHub + +concurrency: + group: GitHub-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + issues: write + pull-requests: write + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + Assign: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + steps: + - uses: pozil/auto-assign-issue@v2.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: NikolaRHristov + numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml new file mode 100644 index 00000000..aef8ed82 --- /dev/null +++ b/.github/workflows/Node.yml @@ -0,0 +1,84 @@ +name: Node + +concurrency: + group: Node-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + push: + branches: [Current] + pull_request: + branches: [Current] + workflow_call: + +jobs: + Pre-Publish: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + + strategy: + matrix: + node-version: [18, 19, 20] + + steps: + - uses: actions/checkout@v4.1.6 + + - uses: pnpm/action-setup@v4.0.0 + with: + version: 8.15.5 + run_install: | + - recursive: true + args: [ + --link-workspace-packages=true, + --lockfile-only, + --prefer-frozen-lockfile=false, + --shamefully-hoist=false, + --shared-workspace-lockfile=true, + --strict-peer-dependencies=false, + --unsafe-perm=true + ] + + - uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: ./pnpm-lock.yaml + + - run: pnpm install + working-directory: . From 5b9d19e57c7f5317daea78490e883554db3ef6b3 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 26 May 2024 14:18:27 +0300 Subject: [PATCH 29/96] squash! --- CHANGELOG.md | 92 +++++++++++++++++++++++++++---------- CODE_OF_CONDUCT.md | 20 ++++---- CONTRIBUTING.md | 23 ++++++---- FUNDING.yml | 1 + LICENSE | 42 ++++++++--------- README.md | 112 ++++++++++++++++++++++++++------------------- ReleaseProcess.md | 22 ++++++--- SECURITY.md | 104 ++++++++++++++++++++++++----------------- copyStaticFiles.js | 46 ++++++++++--------- package.json | 2 +- tsconfig.json | 89 +++++++++++++++++------------------ tslint.json | 16 ++----- 12 files changed, 328 insertions(+), 241 deletions(-) create mode 100644 FUNDING.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a95af5f..37e42ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,78 +1,122 @@ # Change Log -All notable changes to the Deploy to Azure extension will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/). Versioning follows an internal Azure DevOps format that is not compatible with SemVer. +All notable changes to the Deploy to Azure extension will be documented in this +file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/). +Versioning follows an internal Azure DevOps format that is not compatible with +SemVer. ## 1.2.3 + ### Updated -- Moved Simple web app and python linux web app to use remote provisioning. -- Bug fixes -- Removed app id uris being set through the `identifierUris` field while creating the aad app + +- Moved Simple web app and python linux web app to use remote provisioning. +- Bug fixes +- Removed app id uris being set through the `identifierUris` field while + creating the aad app ## 1.2.2 + ### Updated -- Fixed azure pipeline support for Github repository. -- Updated Github PAT permissions needed for workflow commit + +- Fixed azure pipeline support for Github repository. +- Updated Github PAT permissions needed for workflow commit ## 1.2.1 + ### Updated -- Added support for configuring Pipeline remotely in case of .Net and .Net Core deployments to Web Apps. + +- Added support for configuring Pipeline remotely in case of .Net and .Net + Core deployments to Web Apps. ## 1.2.0 + ### Added -- Integrated with [Azure Kubernetes Service extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-aks-tools) to support configure ci/cd on right click of a cluster. + +- Integrated with + [Azure Kubernetes Service extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-aks-tools) + to support configure ci/cd on right click of a cluster. ## 1.1.5 + ### Added -- Added remote configurer for Github Node WebApp. + +- Added remote configurer for Github Node WebApp. ## 1.1.4 + ### Added -- Added remote configurer for Github AKS workflow. + +- Added remote configurer for Github AKS workflow. ## 1.1.3 + ### Added -- Fixed bugs. + +- Fixed bugs. ## 1.1.2 + ### Added -- Fixed session undefined bug. + +- Fixed session undefined bug. ## 1.1.1 + ### Added -- Improved telemetry for better insights. + +- Improved telemetry for better insights. ## 1.1.0 + ### Added -- If not a remote repo, have a provision of creating github repo. -- Added support for selecting the working directory if multiple applications are there to deploy. + +- If not a remote repo, have a provision of creating github repo. +- Added support for selecting the working directory if multiple applications + are there to deploy. ## 1.0.6 + ### Added -- Added telemetry for better insights. + +- Added telemetry for better insights. ## 1.0.5 + ### Added -- Added validations on auto generated GitHub secret names. + +- Added validations on auto generated GitHub secret names. ## 1.0.4 + ### Added -- Added support for Repository Analysis for GitHub repositories. + +- Added support for Repository Analysis for GitHub repositories. ## 1.0.3 + ### Added -- Update README.md. + +- Update README.md. ## 1.0.2 + ### Added -- Configure CI/CD for Github Workflow for Github Repositories. + +- Configure CI/CD for Github Workflow for Github Repositories. ## 1.0.1 + ### Added -- Merged template view for Windows and Linux WebApps. +- Merged template view for Windows and Linux WebApps. ## 1.0.0 + ### Added -- Initial release -- "Configure CI/CD Pipeline" option in Command Palette (Ctrl+Shift+P) and File Explorer. This will configure a continuous integration (CI) and deployment (CD) pipeline to Azure Linux Web App and Function App. + +- Initial release +- "Configure CI/CD Pipeline" option in Command Palette (Ctrl+Shift+P) and File + Explorer. This will configure a continuous integration (CI) and deployment + (CD) pipeline to Azure Linux Web App and Function App. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c72a5749..bb1fb9ac 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,11 @@ -# Microsoft Open Source Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns +# Microsoft Open Source Code of Conduct + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). + +Resources: + +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with + questions or concerns diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54cdd168..2ece56d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,18 @@ # Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.microsoft.com. +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. For +details, visit https://cla.microsoft.com. -When you submit a pull request, a CLA-bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only need +to do this once across all repos using our CLA. -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. diff --git a/FUNDING.yml b/FUNDING.yml new file mode 100644 index 00000000..12f5195d --- /dev/null +++ b/FUNDING.yml @@ -0,0 +1 @@ +open_collective: code-editor-land diff --git a/LICENSE b/LICENSE index 3d8b93bc..9e841e7a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/README.md b/README.md index 02d85b8b..b2c7065c 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,65 @@ -[![Build Status](https://dev.azure.com/mseng/AzureDevOps/_apis/build/status/vscode-deploy-azure-CI)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=9436) - -# Deploy to Azure from Visual Studio Code - -[Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) - - -# 📢 ⛔ ATTENTION!! - Deprecation notice - -This extension is being deprecated and will not be supported. Please see details [here](https://github.com/microsoft/vscode-deploy-azure/issues/239). - ----------------- - - -This Visual Studio Code extension helps you set up continuous build and deployment for Azure App Service or for Azure Kubernetes Service without leaving Visual Studio Code. - -![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) - -To set up a pipeline, choose *Deploy to Azure: Configure CI/CD Pipeline* from the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. The guided workflow will generate a starter YAML file defining the build and deploy process. - -You can customize the pipeline using all the features offered by [Azure Pipelines](https://azure.com/pipelines) and [GitHub Actions.](https://github.com/features/actions/) - -Once the setup is completed, an automatic CI/CD trigger will fire for every code push. To set this up, if you have using GitHub as the repository the extension will ask for a GitHub PAT with *repo* and will configure GitHub Actions. - -![GitHub PAT scope](ghpatpermissions.JPG) - -You can refer to our [tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) for more details on the extension. - -## Telemetry - -Visual Studio Code collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) to learn more. If you don’t wish to send usage data to Microsoft, you can set the `telemetry.enableTelemetry` setting to `false`. Learn more in our [FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). - -## Troubleshooting failures - -- **Failed to determine Azure Repo details from remote url**: If you're configuring a pipeline for a Git repository backed by Azure Repos, ensure that it has a remote pointing to a valid Azure Repos Git repo URL. - -# Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to jump in! - -For TSLint to work in VSCode, run `npm install` and restart VSCode. - -# Testing framework - -For adding test, create test files with extension `.test.ts` inside src/configure/test/suite. - -For running all the tests, use the command `npm test`. +[![Build Status](https://dev.azure.com/mseng/AzureDevOps/_apis/build/status/vscode-deploy-azure-CI)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=9436) + +# Deploy to Azure from Visual Studio Code + +[Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) + +# 📢 ⛔ ATTENTION!! - Deprecation notice + +This extension is being deprecated and will not be supported. Please see details +[here](https://github.com/microsoft/vscode-deploy-azure/issues/239). + +--- + +This Visual Studio Code extension helps you set up continuous build and +deployment for Azure App Service or for Azure Kubernetes Service without leaving +Visual Studio Code. + +![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) + +To set up a pipeline, choose _Deploy to Azure: Configure CI/CD Pipeline_ from +the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. +The guided workflow will generate a starter YAML file defining the build and +deploy process. + +You can customize the pipeline using all the features offered by +[Azure Pipelines](https://azure.com/pipelines) and +[GitHub Actions.](https://github.com/features/actions/) + +Once the setup is completed, an automatic CI/CD trigger will fire for every code +push. To set this up, if you have using GitHub as the repository the extension +will ask for a GitHub PAT with _repo_ and will configure GitHub Actions. + +![GitHub PAT scope](ghpatpermissions.JPG) + +You can refer to our +[tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) +for more details on the extension. + +## Telemetry + +Visual Studio Code collects usage data and sends it to Microsoft to help improve +our products and services. Read our +[privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) +to learn more. If you don’t wish to send usage data to Microsoft, you can set +the `telemetry.enableTelemetry` setting to `false`. Learn more in our +[FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). + +## Troubleshooting failures + +- **Failed to determine Azure Repo details from remote url**: If you're + configuring a pipeline for a Git repository backed by Azure Repos, ensure + that it has a remote pointing to a valid Azure Repos Git repo URL. + +# Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to jump in! + +For TSLint to work in VSCode, run `npm install` and restart VSCode. + +# Testing framework + +For adding test, create test files with extension `.test.ts` inside +src/configure/test/suite. + +For running all the tests, use the command `npm test`. diff --git a/ReleaseProcess.md b/ReleaseProcess.md index 2e316cd9..3e429d7f 100644 --- a/ReleaseProcess.md +++ b/ReleaseProcess.md @@ -1,9 +1,17 @@ **Process for releasing a new version of VSCode extension - Deploy to Azure** -1. Update the new version in package.json and package-lock.json -2. Add concise description of the changes in the new version in ChangeLog.md and make changes in README.(if required). -3. Create a release branch for every major version update. Example, for version v1,v2,v3, create new branch : releases/v1, releases/v2, releases/v3. -4. Run the [pipeline](https://dev.azure.com/mseng/AzureDevOps/_build?definitionId=9571&_a=summary) with the release branch created. -5. Download the artifacts and get the [BVT testing](https://drive.google.com/file/d/1vLZ1I-LObjnV-6L3CPOSll1gbH4TJwA-/view?usp=sharing) done using the corresponding Vsix with the vendor team. -6. Create a tag for the corresponding version, using [Draft a new release](https://github.com/microsoft/vscode-deploy-azure/releases). -7. Upload the VSIX at the [marketplace](https://marketplace.visualstudio.com/manage/publishers/ms-vscode-deploy-azure?noPrompt=true). +1. Update the new version in package.json and package-lock.json +2. Add concise description of the changes in the new version in ChangeLog.md and + make changes in README.(if required). +3. Create a release branch for every major version update. Example, for version + v1,v2,v3, create new branch : releases/v1, releases/v2, releases/v3. +4. Run the + [pipeline](https://dev.azure.com/mseng/AzureDevOps/_build?definitionId=9571&_a=summary) + with the release branch created. +5. Download the artifacts and get the + [BVT testing](https://drive.google.com/file/d/1vLZ1I-LObjnV-6L3CPOSll1gbH4TJwA-/view?usp=sharing) + done using the corresponding Vsix with the vendor team. +6. Create a tag for the corresponding version, using + [Draft a new release](https://github.com/microsoft/vscode-deploy-azure/releases). +7. Upload the VSIX at the + [marketplace](https://marketplace.visualstudio.com/manage/publishers/ms-vscode-deploy-azure?noPrompt=true). diff --git a/SECURITY.md b/SECURITY.md index 7ab49eb8..4fe08faf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,41 +1,63 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - + + +## Security + +Microsoft takes the security of our software products and services seriously, +which includes all source code repositories managed through our GitHub +organizations, which include [Microsoft](https://github.com/Microsoft), +[Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), +[AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and +[our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned +repository that meets Microsoft's +[Microsoft's definition of a security vulnerability]() +of a security vulnerability, please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at +[https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). + +If you prefer to submit without logging in, send email to +[secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your +message with our PGP key; please download it from the the +[Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). + +You should receive a response within 24 hours. If for some reason you do not, +please follow up via email to ensure we received your original message. +Additional information can be found at +[microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can +provide) to help us better understand the nature and scope of the possible +issue: + +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, + etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a +higher bounty award. Please visit our +[Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more +details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of +[Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). + + diff --git a/copyStaticFiles.js b/copyStaticFiles.js index 029f7ab4..f2c88990 100644 --- a/copyStaticFiles.js +++ b/copyStaticFiles.js @@ -1,34 +1,36 @@ "use strict"; -var path = require('path'); -var shell = require('shelljs'); +var path = require("path"); +var shell = require("shelljs"); //------------------------------------------------------------------------------ // shell functions //------------------------------------------------------------------------------ var shellAssert = function () { - var errMsg = shell.error(); - if (errMsg) { - throw new Error(errMsg); - } + var errMsg = shell.error(); + if (errMsg) { + throw new Error(errMsg); + } }; var cp = function (options, source, dest) { - if (dest) { - shell.cp(options, source, dest); - } - else { - shell.cp(options, source); - } - shellAssert(); + if (dest) { + shell.cp(options, source, dest); + } else { + shell.cp(options, source); + } + shellAssert(); }; var mkdir = function (options, target) { - if (target) { - shell.mkdir(options, target); - } - else { - shell.mkdir(options); - } - shellAssert(); + if (target) { + shell.mkdir(options, target); + } else { + shell.mkdir(options); + } + shellAssert(); }; -mkdir("-p", path.join(__dirname, 'out/configure/templates')); -cp("-Rf", path.join(__dirname, 'src/configure/templates/*'), path.join(__dirname, 'out/configure/templates')); +mkdir("-p", path.join(__dirname, "out/configure/templates")); +cp( + "-Rf", + path.join(__dirname, "src/configure/templates/*"), + path.join(__dirname, "out/configure/templates"), +); //# sourceMappingURL=copyStaticFiles.js.map diff --git a/package.json b/package.json index 03392110..e1c4d518 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "ajv": "8.13.0", "assert": "2.1.0", "chai": "5.1.1", - "glob": "10.3.16", + "glob": "10.4.1", "nock": "13.5.4", "typescript-tslint-plugin": "0.5.5" }, diff --git a/tsconfig.json b/tsconfig.json index 8b117581..f37a4f03 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,39 +1,39 @@ { - "compilerOptions": { - /* Parse in strict mode and emit "use strict" for each source file. */ - "alwaysStrict": true, + "compilerOptions": { + /* Parse in strict mode and emit "use strict" for each source file. */ + "alwaysStrict": true, - /* List of library files to be included in the compilation. */ - "lib": [ "es6" ], + /* List of library files to be included in the compilation. */ + "lib": ["es6"], - /* Specify module code generation. */ - "module": "commonjs", + /* Specify module code generation. */ + "module": "commonjs", - /* */ - "moduleResolution": "node", + /* */ + "moduleResolution": "node", - /* Report errors for fallthrough cases in switch statement. */ - "noFallthroughCasesInSwitch": true, + /* Report errors for fallthrough cases in switch statement. */ + "noFallthroughCasesInSwitch": true, - /* Report error when not all code paths in function return a value. */ - "noImplicitReturns": true, + /* Report error when not all code paths in function return a value. */ + "noImplicitReturns": true, - /* Report errors on unused locals. */ - "noUnusedLocals": true, + /* Report errors on unused locals. */ + "noUnusedLocals": true, - /* Report errors on unused parameters. */ - //"noUnusedParameters": true, + /* Report errors on unused parameters. */ + //"noUnusedParameters": true, - /* Redirect output structure to the directory. */ - "outDir": "out", + /* Redirect output structure to the directory. */ + "outDir": "out", - /* Specifies the root directory of input files. Only use to control the output directory structure with --outDir. */ - "rootDir": "src", + /* Specifies the root directory of input files. Only use to control the output directory structure with --outDir. */ + "rootDir": "src", - /* Generates corresponding .map file. */ - "sourceMap": true, + /* Generates corresponding .map file. */ + "sourceMap": true, - /* Enable all strict type checking options. + /* Enable all strict type checking options. Enabling --strict enables --noImplicitAny, --noImplicitThis, @@ -42,27 +42,20 @@ --strictFunctionTypes --strictPropertyInitialization. */ - //"strict": true, - - /* Specify ECMAScript target version. */ - "target": "es6", - - /* */ - "allowJs": true, - - "plugins": [ - { - "name": "typescript-tslint-plugin" - } - ] - }, - "include": [ - "src/**/*", - "src/credentialstore/bin/win32/creds.exe" - ], - "exclude": [ - "node_modules", - ".vscode-test", - "tools/**" - ] -} \ No newline at end of file + //"strict": true, + + /* Specify ECMAScript target version. */ + "target": "es6", + + /* */ + "allowJs": true, + + "plugins": [ + { + "name": "typescript-tslint-plugin" + } + ] + }, + "include": ["src/**/*", "src/credentialstore/bin/win32/creds.exe"], + "exclude": ["node_modules", ".vscode-test", "tools/**"] +} diff --git a/tslint.json b/tslint.json index 26c084c5..ec10dc13 100644 --- a/tslint.json +++ b/tslint.json @@ -1,17 +1,12 @@ { - "rulesDirectory": [ - "node_modules/tslint-microsoft-contrib" - ], + "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], "rules": { "no-string-throw": true, "no-unused-expression": true, "no-duplicate-variable": true, "curly": true, "class-name": true, - "semicolon": [ - true, - "always" - ], + "semicolon": [true, "always"], "triple-equals": false, "no-banned-terms": true, "no-delete-expression": true, @@ -59,8 +54,5 @@ "non-literal-fs-path": false }, "defaultSeverity": "warning", - "extends": [ - "tslint-microsoft-contrib/recommended", - "tslint:recommended" - ] -} \ No newline at end of file + "extends": ["tslint-microsoft-contrib/recommended", "tslint:recommended"] +} From c9ae0cdede55f83b9edda2e7bdedde158aa1945b Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 26 May 2024 22:15:55 +0300 Subject: [PATCH 30/96] squash! --- FUNDING.yml => .github/FUNDING.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename FUNDING.yml => .github/FUNDING.yml (100%) diff --git a/FUNDING.yml b/.github/FUNDING.yml similarity index 100% rename from FUNDING.yml rename to .github/FUNDING.yml From dda66816beacc9094df6dcd50f0d568a6f84fd1d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 27 May 2024 17:00:22 +0300 Subject: [PATCH 31/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 3d41c8969e7db0a49ad062c5132bcba0598c390b Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 6 Jun 2024 01:32:04 +0300 Subject: [PATCH 32/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..128a50ab 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^11.2.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "mustache": "4.2.0", + "q": "1.5.1", + "semver": "^7.6.2", + "shelljs": "^0.8.5", + "simple-git": "^3.24.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.8.11", + "underscore": "1.13.6", + "uuid": "^9.0.1", + "yaml-language-server": "^1.14.0" + }, + "devDependencies": { + "@types/fs-extra": "11.0.4", + "@types/glob": "^8.1.0", + "@types/js-yaml": "^4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "^20.14.0", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "^8.15.0", + "assert": "2.1.0", + "chai": "^5.1.1", + "glob": "^10.4.1", + "nock": "^13.5.4", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From fbcfa5c7a26b86f09959b086f1afa57300b9d3dd Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 8 Jun 2024 07:33:36 +0300 Subject: [PATCH 33/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 1e681e3fbf82aeb0f032d9e97a1e5f36a43ce7d4 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 9 Jun 2024 19:17:51 +0300 Subject: [PATCH 34/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 127 files changed, 21483 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From e5fec65ba0bb5a7392a5451681d91382ec9ded52 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 9 Jun 2024 19:24:06 +0300 Subject: [PATCH 35/96] squash! --- package.json | 283 +++++++++++++++++++++------------------------------ 1 file changed, 116 insertions(+), 167 deletions(-) diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} From aa2b29d21437b908f6c3290c5a1c57fb37374f1c Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 11 Jun 2024 16:21:43 +0300 Subject: [PATCH 36/96] squash! --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 64e0e50c..b1758e50 100644 --- a/package.json +++ b/package.json @@ -70,34 +70,34 @@ } }, "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", + "fs-extra": "^11.2.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "^7.6.2", + "shelljs": "^0.8.5", + "simple-git": "^3.24.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "typed-rest-client": "2.0.0", + "underscore": "1.13.6", + "uuid": "^10.0.0", + "yaml-language-server": "^1.15.0" }, "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", + "@types/fs-extra": "11.0.4", + "@types/glob": "^8.1.0", + "@types/js-yaml": "^4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "^20.14.2", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "^8.16.0", + "assert": "2.1.0", + "chai": "^5.1.1", + "glob": "^10.4.1", + "nock": "^13.5.4", "typescript-tslint-plugin": "^0.5.5" }, "displayName": "Deploy to Azure", From 74a0e7cd5a26700efbf81f37cb509e015f364c90 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 11 Jun 2024 17:12:55 +0300 Subject: [PATCH 37/96] squash! --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b1758e50..711369af 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "q": "1.5.1", "semver": "^7.6.2", "shelljs": "^0.8.5", - "simple-git": "^3.24.0", + "simple-git": "^3.25.0", "tweetsodium": "0.0.4", "typed-rest-client": "2.0.0", "underscore": "1.13.6", From f6c196812108f2961a99d2f59402edc1499f2617 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 12 Jun 2024 12:45:21 +0300 Subject: [PATCH 38/96] squash! --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 711369af..e959e4d0 100644 --- a/package.json +++ b/package.json @@ -70,35 +70,35 @@ } }, "dependencies": { - "fs-extra": "^11.2.0", - "js-yaml": "^4.1.0", - "jsonpath-plus": "^9.0.0", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.6.2", - "shelljs": "^0.8.5", - "simple-git": "^3.25.0", + "semver": "7.6.2", + "shelljs": "0.8.5", + "simple-git": "3.25.0", "tweetsodium": "0.0.4", "typed-rest-client": "2.0.0", "underscore": "1.13.6", - "uuid": "^10.0.0", - "yaml-language-server": "^1.15.0" + "uuid": "10.0.0", + "yaml-language-server": "1.15.0" }, "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", - "@types/glob": "^8.1.0", - "@types/js-yaml": "^4.0.9", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "^20.14.2", + "@types/node": "20.14.2", "@types/q": "1.5.8", "@types/underscore": "1.11.15", - "ajv": "^8.16.0", + "ajv": "8.16.0", "assert": "2.1.0", - "chai": "^5.1.1", - "glob": "^10.4.1", - "nock": "^13.5.4", - "typescript-tslint-plugin": "^0.5.5" + "chai": "5.1.1", + "glob": "10.4.1", + "nock": "13.5.4", + "typescript-tslint-plugin": "0.5.5" }, "displayName": "Deploy to Azure", "extensionDependencies": [ From 362537fd1574f30eef0f1533d8cceda0c9e52951 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 12 Jun 2024 22:03:52 +0300 Subject: [PATCH 39/96] squash! --- .github/workflows/Node.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml index aef8ed82..c2c84de6 100644 --- a/.github/workflows/Node.yml +++ b/.github/workflows/Node.yml @@ -61,7 +61,7 @@ jobs: - uses: pnpm/action-setup@v4.0.0 with: - version: 8.15.5 + version: 9.3.0 run_install: | - recursive: true args: [ From fac927a018e157d480370c67407bf6ae22236aa9 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 13 Jun 2024 18:29:04 +0300 Subject: [PATCH 40/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From d1d70e5e7427928ee8c12810ff4ef715628e3fa3 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 16 Jun 2024 16:41:29 +0300 Subject: [PATCH 41/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 128 files changed, 116 insertions(+), 9086 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..e6129509 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^11.2.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "mustache": "4.2.0", + "q": "1.5.1", + "semver": "^7.6.2", + "shelljs": "^0.8.5", + "simple-git": "^3.25.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "2.0.0", + "underscore": "1.13.6", + "uuid": "^10.0.0", + "yaml-language-server": "^1.15.0" + }, + "devDependencies": { + "@types/fs-extra": "11.0.4", + "@types/glob": "^8.1.0", + "@types/js-yaml": "^4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "^20.14.2", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "^8.16.0", + "assert": "2.1.0", + "chai": "^5.1.1", + "glob": "^10.4.1", + "nock": "^13.5.4", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From 04a66126817687360b5dba131ff06eec6af1d230 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 19 Jun 2024 02:50:39 +0300 Subject: [PATCH 42/96] squash! --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 4e145024..8162f80a 100644 --- a/package.json +++ b/package.json @@ -76,33 +76,33 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", + "fs-extra": "^11.2.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "^7.6.2", + "shelljs": "^0.8.5", + "simple-git": "^3.25.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "typed-rest-client": "2.0.0", + "underscore": "1.13.6", + "uuid": "^10.0.0", + "yaml-language-server": "^1.15.0" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", + "@types/fs-extra": "11.0.4", + "@types/glob": "^8.1.0", + "@types/js-yaml": "^4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "^20.14.5", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "^8.16.0", + "assert": "2.1.0", + "chai": "^5.1.1", + "glob": "^10.4.1", + "nock": "^13.5.4", "typescript-tslint-plugin": "^0.5.5" }, "extensionDependencies": [ From bbff518f306fd7e06e6ec6f8c2142024378fc5b3 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 19 Jun 2024 02:56:24 +0300 Subject: [PATCH 43/96] squash! --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 8162f80a..86c7387c 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^11.2.0", - "js-yaml": "^4.1.0", - "jsonpath-plus": "^9.0.0", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.6.2", - "shelljs": "^0.8.5", - "simple-git": "^3.25.0", + "semver": "7.6.2", + "shelljs": "0.8.5", + "simple-git": "3.25.0", "tweetsodium": "0.0.4", "typed-rest-client": "2.0.0", "underscore": "1.13.6", - "uuid": "^10.0.0", - "yaml-language-server": "^1.15.0" + "uuid": "10.0.0", + "yaml-language-server": "1.15.0" }, "devDependencies": { "@types/fs-extra": "11.0.4", - "@types/glob": "^8.1.0", - "@types/js-yaml": "^4.0.9", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "^20.14.5", + "@types/node": "20.14.5", "@types/q": "1.5.8", "@types/underscore": "1.11.15", - "ajv": "^8.16.0", + "ajv": "8.16.0", "assert": "2.1.0", - "chai": "^5.1.1", - "glob": "^10.4.1", - "nock": "^13.5.4", - "typescript-tslint-plugin": "^0.5.5" + "chai": "5.1.1", + "glob": "10.4.1", + "nock": "13.5.4", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From 1ab037d9a50809f5815989495408f6a2e2f05b56 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 19 Jun 2024 21:56:30 +0300 Subject: [PATCH 44/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From a4b306c1ba8f159699f9cb36f6bc484c35fb1c17 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 20 Jun 2024 15:10:31 +0300 Subject: [PATCH 45/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 69afba3157bbab150808469e3fe911315e41a3bf Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 20 Jun 2024 19:03:55 +0300 Subject: [PATCH 46/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 127 files changed, 21483 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 76c22e5ca608a8e02863515d69d8b4dc8965a4bb Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 20 Jun 2024 23:20:25 +0300 Subject: [PATCH 47/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From ceb15f62f91e5b23852e5b94953b992718618749 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 22 Jun 2024 21:08:29 +0300 Subject: [PATCH 48/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 84c33202393a23d0eea7b1759fbac323cd4c12c8 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 24 Jun 2024 02:17:56 +0300 Subject: [PATCH 49/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 9ac0bc41f92e8436a94de894a5e966047cd02832 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 25 Jun 2024 01:08:47 +0300 Subject: [PATCH 50/96] squash! --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 4e145024..09435409 100644 --- a/package.json +++ b/package.json @@ -76,33 +76,33 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", + "fs-extra": "^11.2.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "^7.6.2", + "shelljs": "^0.8.5", + "simple-git": "^3.25.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "typed-rest-client": "2.0.0", + "underscore": "1.13.6", + "uuid": "^10.0.0", + "yaml-language-server": "^1.15.0" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", + "@types/fs-extra": "11.0.4", + "@types/glob": "^8.1.0", + "@types/js-yaml": "^4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "^20.14.8", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "^8.16.0", + "assert": "2.1.0", + "chai": "^5.1.1", + "glob": "^10.4.2", + "nock": "^13.5.4", "typescript-tslint-plugin": "^0.5.5" }, "extensionDependencies": [ From 4dbd3e077c10391dacc7cc56fe57d423d5803d82 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 27 Jun 2024 09:24:48 +0300 Subject: [PATCH 51/96] squash! --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 09435409..a2f1465b 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^11.2.0", - "js-yaml": "^4.1.0", - "jsonpath-plus": "^9.0.0", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.6.2", - "shelljs": "^0.8.5", - "simple-git": "^3.25.0", + "semver": "7.6.2", + "shelljs": "0.8.5", + "simple-git": "3.25.0", "tweetsodium": "0.0.4", "typed-rest-client": "2.0.0", "underscore": "1.13.6", - "uuid": "^10.0.0", - "yaml-language-server": "^1.15.0" + "uuid": "10.0.0", + "yaml-language-server": "1.15.0" }, "devDependencies": { "@types/fs-extra": "11.0.4", - "@types/glob": "^8.1.0", - "@types/js-yaml": "^4.0.9", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "^20.14.8", + "@types/node": "20.14.8", "@types/q": "1.5.8", "@types/underscore": "1.11.15", - "ajv": "^8.16.0", + "ajv": "8.16.0", "assert": "2.1.0", - "chai": "^5.1.1", - "glob": "^10.4.2", - "nock": "^13.5.4", - "typescript-tslint-plugin": "^0.5.5" + "chai": "5.1.1", + "glob": "10.4.2", + "nock": "13.5.4", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From 8bee952636ec87f0e9e5d31a0f97eb8d213388d1 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 27 Jun 2024 10:55:11 +0300 Subject: [PATCH 52/96] squash! --- .github/workflows/Node.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml index c2c84de6..183acee8 100644 --- a/.github/workflows/Node.yml +++ b/.github/workflows/Node.yml @@ -57,7 +57,7 @@ jobs: node-version: [18, 19, 20] steps: - - uses: actions/checkout@v4.1.6 + - uses: actions/checkout@v4.1.7 - uses: pnpm/action-setup@v4.0.0 with: From da43b2389c024d11a0dfa342b613f52decc0ec64 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 28 Jun 2024 01:33:28 +0300 Subject: [PATCH 53/96] squash! --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a2f1465b..26f71ef2 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "shelljs": "0.8.5", "simple-git": "3.25.0", "tweetsodium": "0.0.4", - "typed-rest-client": "2.0.0", + "typed-rest-client": "2.0.1", "underscore": "1.13.6", "uuid": "10.0.0", "yaml-language-server": "1.15.0" @@ -95,7 +95,7 @@ "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "20.14.8", + "@types/node": "20.14.9", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.16.0", From 94ec8062dc18c9805ac7b5cd120b6fa6c0128075 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 30 Jun 2024 08:21:40 +0300 Subject: [PATCH 54/96] squash! --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 26f71ef2..e5d3ed90 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,8 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - }, + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "contributes": { "commands": [ { @@ -72,9 +69,6 @@ ] } }, - "activationEvents": [ - "*" - ], "dependencies": { "fs-extra": "11.2.0", "js-yaml": "4.1.0", @@ -90,6 +84,7 @@ "uuid": "10.0.0", "yaml-language-server": "1.15.0" }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -105,13 +100,18 @@ "nock": "13.5.4", "typescript-tslint-plugin": "0.5.5" }, + "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } } From 7fddeafe22a454855f6e2373e09630955087da71 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 30 Jun 2024 08:28:12 +0300 Subject: [PATCH 55/96] squash! --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index e5d3ed90..26f71ef2 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, "contributes": { "commands": [ { @@ -69,6 +72,9 @@ ] } }, + "activationEvents": [ + "*" + ], "dependencies": { "fs-extra": "11.2.0", "js-yaml": "4.1.0", @@ -84,7 +90,6 @@ "uuid": "10.0.0", "yaml-language-server": "1.15.0" }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -100,18 +105,13 @@ "nock": "13.5.4", "typescript-tslint-plugin": "0.5.5" }, - "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], + "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "icon": "assets/deployToAzure.png", - "main": "./out/extension", - "name": "azure-deploy", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - } + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } From 2fa5b2326826382244a064bcaf8eaa0dbb18e247 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 8 Jul 2024 16:14:41 +0300 Subject: [PATCH 56/96] squash! --- CODE_OF_CONDUCT.md | 155 ++++++++++++++++++++++++++++++++++++++++++--- LICENSE | 41 ++++++------ 2 files changed, 166 insertions(+), 30 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c72a5749..d35c6688 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,146 @@ -# Microsoft Open Source Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns +# Code of Conduct + +## Our Pledge + +Welcome to our community! We are committed to creating a welcoming and inclusive +environment for all contributors. As members, contributors, and leaders, we +pledge to make participation in our community a harassment-free experience for +everyone, regardless of: + +- Age +- Body size +- Visible or invisible disability +- Ethnicity +- Sex characteristics +- Gender identity and expression +- Level of experience +- Education +- Socio-economic status +- Nationality +- Personal appearance +- Race +- Caste +- Color +- Religion +- Sexual identity and orientation + +We promise to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances + of any kind +- Trolling, insulting, or derogatory comments, and personal or political + attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior. They will take appropriate and fair corrective action in +response to any behavior they deem inappropriate, threatening, offensive, or +harmful. This may include removing, editing, or rejecting comments, commits, +code, wiki edits, issues, and other contributions that do not align with this +Code of Conduct. Community leaders will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +Community@PlayForm.Cloud. All complaints will be reviewed and investigated +promptly and fairly. All community leaders are obligated to respect the privacy +and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + +Thank you for being part of our community and helping us create a safe and +respectful environment for everyone! diff --git a/LICENSE b/LICENSE index 3d8b93bc..f236d76d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,20 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE +MIT License + +Copyright (c) 2023-2024 PlayForm + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 8715815eec81385b4ecc1c3a43c934856af87cd4 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 9 Jul 2024 22:08:20 +0300 Subject: [PATCH 57/96] squash! --- .github/workflows/Dependabot.yml | 4 ++-- .github/workflows/GitHub.yml | 1 + .github/workflows/Node.yml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml index e6091e54..387fece7 100644 --- a/.github/workflows/Dependabot.yml +++ b/.github/workflows/Dependabot.yml @@ -20,7 +20,7 @@ jobs: if: ${{ github.actor == 'dependabot[bot]' }} steps: - - uses: dependabot/fetch-metadata@v2.1.0 + - uses: dependabot/fetch-metadata@v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" @@ -35,7 +35,7 @@ jobs: if: ${{ github.actor == 'dependabot[bot]' }} steps: - - uses: dependabot/fetch-metadata@v2.1.0 + - uses: dependabot/fetch-metadata@v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml index 5e814e3e..7b1e399c 100644 --- a/.github/workflows/GitHub.yml +++ b/.github/workflows/GitHub.yml @@ -48,6 +48,7 @@ jobs: STNOUPGRADE: 1 STRIPE_CLI_TELEMETRY_OPTOUT: 1 TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 steps: - uses: pozil/auto-assign-issue@v2.0.0 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml index 183acee8..01f0a9ed 100644 --- a/.github/workflows/Node.yml +++ b/.github/workflows/Node.yml @@ -51,6 +51,7 @@ jobs: STNOUPGRADE: 1 STRIPE_CLI_TELEMETRY_OPTOUT: 1 TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 strategy: matrix: From 614bd68358fcfc3cab9b720106dcf319041de1a9 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 10 Jul 2024 14:03:31 +0300 Subject: [PATCH 58/96] squash! --- .github/dependabot.yml | 14 ---------- .github/workflows/Dependabot.yml | 45 -------------------------------- 2 files changed, 59 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index 387fece7..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From c8cfa9810d38b1d5b9286181c042ad115363e7fb Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 13 Jul 2024 03:24:29 +0300 Subject: [PATCH 59/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 93c1d404e03d106c0a3e73414018292114ac0d61 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 14 Jul 2024 03:13:29 +0300 Subject: [PATCH 60/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 128 files changed, 116 insertions(+), 21650 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From c3b7155fd1b32bd52b5e290232ef222ac73a747d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 14 Jul 2024 16:37:01 +0300 Subject: [PATCH 61/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 128 files changed, 116 insertions(+), 9086 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From 8ac58b9587e62fd98aa9a5b914ab0cb2a36474c1 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 15 Jul 2024 03:07:48 +0300 Subject: [PATCH 62/96] squash! --- {src => Source}/configure/test/index.ts | 0 {src => Source}/configure/test/runTest.ts | 0 .../configure/test/suite/GitHubClient.test.ts | 0 .../configure/test/suite/commonHelper.test.ts | 0 src/configure/activate.ts | 43 - src/configure/browse.ts | 100 -- .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 -- src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 -- .../clients/devOps/azureDevOpsClient.ts | 371 ---- .../clients/devOps/serviceConnectionClient.ts | 241 --- .../clients/github/TemplateServiceClient.ts | 112 -- src/configure/clients/github/githubClient.ts | 156 -- .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 --------- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 ----- src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 ---- .../configurers/provisioningConfigurer.ts | 304 ---- .../remoteGitHubWorkflowConfigurer.ts | 247 --- src/configure/helper/AssetHandler.ts | 169 -- src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 --- src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 -- src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 -- .../helper/devOps/serviceConnectionHelper.ts | 123 -- src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 --- src/configure/helper/mustacheHelper.ts | 288 ---- .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 -- .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ----------------- .../helper/templateParameterHelper.ts | 278 --- src/configure/model/Contracts.ts | 294 ---- src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 ---- .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 -- src/configure/resources/constants.ts | 203 --- src/configure/resources/messages.ts | 126 -- src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 ---- .../InputControlProvider.ts | 268 --- .../RepoAnalysisSettingInputProvider.ts | 109 -- .../utilities/DataSourceExpression.ts | 174 -- .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 -- .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 -- .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 -- .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/utilities/templateConverter.ts | 108 -- src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 115 files changed, 12564 deletions(-) rename {src => Source}/configure/test/index.ts (100%) rename {src => Source}/configure/test/runTest.ts (100%) rename {src => Source}/configure/test/suite/GitHubClient.test.ts (100%) rename {src => Source}/configure/test/suite/commonHelper.test.ts (100%) delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/src/configure/test/index.ts b/Source/configure/test/index.ts similarity index 100% rename from src/configure/test/index.ts rename to Source/configure/test/index.ts diff --git a/src/configure/test/runTest.ts b/Source/configure/test/runTest.ts similarity index 100% rename from src/configure/test/runTest.ts rename to Source/configure/test/runTest.ts diff --git a/src/configure/test/suite/GitHubClient.test.ts b/Source/configure/test/suite/GitHubClient.test.ts similarity index 100% rename from src/configure/test/suite/GitHubClient.test.ts rename to Source/configure/test/suite/GitHubClient.test.ts diff --git a/src/configure/test/suite/commonHelper.test.ts b/Source/configure/test/suite/commonHelper.test.ts similarity index 100% rename from src/configure/test/suite/commonHelper.test.ts rename to Source/configure/test/suite/commonHelper.test.ts diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 51c986b0906e29aa17e32c288bd87c06b7c0079d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 15 Jul 2024 03:38:29 +0300 Subject: [PATCH 63/96] squash! --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - Source/configure/test/index.ts | 38 - Source/configure/test/runTest.ts | 23 - .../configure/test/suite/GitHubClient.test.ts | 122 - .../configure/test/suite/commonHelper.test.ts | 80 - package-lock.json | 7999 ----------------- package.json | 283 +- 17 files changed, 116 insertions(+), 9086 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 Source/configure/test/index.ts delete mode 100644 Source/configure/test/runTest.ts delete mode 100644 Source/configure/test/suite/GitHubClient.test.ts delete mode 100644 Source/configure/test/suite/commonHelper.test.ts delete mode 100644 package-lock.json diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/Source/configure/test/index.ts b/Source/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/Source/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/Source/configure/test/runTest.ts b/Source/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/Source/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/Source/configure/test/suite/GitHubClient.test.ts b/Source/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/Source/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/Source/configure/test/suite/commonHelper.test.ts b/Source/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/Source/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} From ee5078a59d024d6bdc27c83dc35881f1ea33642a Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 17 Jul 2024 22:41:21 +0300 Subject: [PATCH 64/96] --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 4e145024..f91d7dd1 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", + "fs-extra": "9.0.1", + "js-yaml": "3.13.1", + "jsonpath-plus": "3.0.0", "mustache": "3.0.1", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.3.2", + "shelljs": "0.3.0", + "simple-git": "1.110.0", "tweetsodium": "0.0.4", "typed-rest-client": "1.0.7", "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "uuid": "3.3.2", + "yaml-language-server": "0.8.0" }, "devDependencies": { "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", + "@types/glob": "7.1.1", + "@types/js-yaml": "3.12.1", "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", + "@types/node": "7.0.43", "@types/q": "1.5.0", "@types/underscore": "1.8.9", - "ajv": "^6.9.1", + "ajv": "6.9.1", "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", - "typescript-tslint-plugin": "^0.5.5" + "chai": "4.2.0", + "glob": "7.1.6", + "nock": "13.0.2", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From dd8281d2375f6d86e6a005c677d6ea7ba2e1599a Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 18 Jul 2024 07:48:38 +0300 Subject: [PATCH 65/96] --- .github/workflows/defaultLabel.yml | 21 --------------------- .github/workflows/stale.yml | 20 -------------------- 2 files changed, 41 deletions(-) delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" From 5375a80acd4dbdc42ec755773f32d4b128079635 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 19 Jul 2024 04:30:31 +0300 Subject: [PATCH 66/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 128 files changed, 116 insertions(+), 9086 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "activationEvents": [ + "*" + ], + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From 6b570cb04612036115ee2b47123f739c1dc5d649 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 19 Jul 2024 07:57:08 +0300 Subject: [PATCH 67/96] --- package.json | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 4e145024..e2a1ef78 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.6.3", + "shelljs": "0.8.5", + "simple-git": "3.25.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "typed-rest-client": "2.0.2", + "underscore": "1.13.6", + "uuid": "10.0.0", + "yaml-language-server": "1.15.1-f039273.0" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", - "typescript-tslint-plugin": "^0.5.5" + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "20.14.11", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.17.1", + "assert": "2.1.0", + "chai": "5.1.1", + "glob": "11.0.0", + "nock": "14.0.0-beta.8", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From c52ccbbfe24848023e77264386ce061639167e16 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 22 Jul 2024 19:01:34 +0300 Subject: [PATCH 68/96] --- .github/dependabot.yml | 14 ++++++++++ .github/workflows/Dependabot.yml | 45 ++++++++++++++++++++++++++++++++ .github/workflows/Node.yml | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..387fece7 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml index 01f0a9ed..dfdd1814 100644 --- a/.github/workflows/Node.yml +++ b/.github/workflows/Node.yml @@ -75,7 +75,7 @@ jobs: --unsafe-perm=true ] - - uses: actions/setup-node@v4.0.2 + - uses: actions/setup-node@v4.0.3 with: node-version: ${{ matrix.node-version }} cache: "pnpm" From e37820b313ac78ea0ebd1be4e1bb79d8b6ac9268 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 23 Jul 2024 11:35:36 +0300 Subject: [PATCH 69/96] --- .github/dependabot.yml | 14 ------ .github/workflows/Dependabot.yml | 45 ----------------- .github/workflows/GitHub.yml | 58 ---------------------- .github/workflows/Node.yml | 85 -------------------------------- 4 files changed, 202 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml delete mode 100644 .github/workflows/GitHub.yml delete mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index 387fece7..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml deleted file mode 100644 index 7b1e399c..00000000 --- a/.github/workflows/GitHub.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: GitHub - -concurrency: - group: GitHub-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - issues: write - pull-requests: write - -on: - issues: - types: [opened] - pull_request: - types: [opened] - -jobs: - Assign: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - steps: - - uses: pozil/auto-assign-issue@v2.0.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: NikolaRHristov - numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml deleted file mode 100644 index dfdd1814..00000000 --- a/.github/workflows/Node.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Node - -concurrency: - group: Node-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - push: - branches: [Current] - pull_request: - branches: [Current] - workflow_call: - -jobs: - Pre-Publish: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - strategy: - matrix: - node-version: [18, 19, 20] - - steps: - - uses: actions/checkout@v4.1.7 - - - uses: pnpm/action-setup@v4.0.0 - with: - version: 9.3.0 - run_install: | - - recursive: true - args: [ - --link-workspace-packages=true, - --lockfile-only, - --prefer-frozen-lockfile=false, - --shamefully-hoist=false, - --shared-workspace-lockfile=true, - --strict-peer-dependencies=false, - --unsafe-perm=true - ] - - - uses: actions/setup-node@v4.0.3 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./pnpm-lock.yaml - - - run: pnpm install - working-directory: . From be94f27fed4d3c57559b6ff6fb90c36f2fe6572d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 24 Jul 2024 15:21:20 +0300 Subject: [PATCH 70/96] --- package.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index f91d7dd1..9c8951a0 100644 --- a/package.json +++ b/package.json @@ -76,33 +76,33 @@ "*" ], "dependencies": { - "fs-extra": "9.0.1", - "js-yaml": "3.13.1", - "jsonpath-plus": "3.0.0", - "mustache": "3.0.1", + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", + "mustache": "4.2.0", "q": "1.5.1", - "semver": "7.3.2", - "shelljs": "0.3.0", - "simple-git": "1.110.0", + "semver": "7.6.3", + "shelljs": "0.8.5", + "simple-git": "3.25.0", "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "3.3.2", - "yaml-language-server": "0.8.0" + "typed-rest-client": "2.0.2", + "underscore": "1.13.6", + "uuid": "10.0.0", + "yaml-language-server": "1.15.1-f039273.0" }, "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "7.1.1", - "@types/js-yaml": "3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "6.9.1", - "assert": "1.4.1", - "chai": "4.2.0", - "glob": "7.1.6", - "nock": "13.0.2", + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "20.14.12", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.17.1", + "assert": "2.1.0", + "chai": "5.1.1", + "glob": "11.0.0", + "nock": "14.0.0-beta.8", "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ From 86e5039bca80ec8829201f633efe21b258ca490c Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 25 Jul 2024 13:58:36 +0300 Subject: [PATCH 71/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 131 files changed, 116 insertions(+), 9128 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From 9dee06133a6d4c26b4a1f1fd7df79fd16742ba3d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 25 Jul 2024 19:34:01 +0300 Subject: [PATCH 72/96] --- package.json | 283 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 167 insertions(+), 116 deletions(-) diff --git a/package.json b/package.json index 9c8951a0..9d4182a2 100644 --- a/package.json +++ b/package.json @@ -1,117 +1,168 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - }, - "contributes": { - "commands": [ - { - "category": "Deploy to Azure", - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline" - }, - { - "category": "Deploy to Azure", - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline" - } - ], - "configuration": { - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", - "type": "boolean" - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "default": true, - "description": "Use GitHub for creating new repository", - "type": "boolean" - } - }, - "title": "Deploy to Azure" - }, - "grammars": [ - { - "language": "yaml", - "path": "./syntaxes/yaml.tmLanguage.json", - "scopeName": "source.yaml" - } - ], - "languages": [ - { - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ], - "id": "yaml" - } - ], - "menus": { - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ], - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ] - } - }, - "activationEvents": [ - "*" - ], - "dependencies": { - "fs-extra": "11.2.0", - "js-yaml": "4.1.0", - "jsonpath-plus": "9.0.0", - "mustache": "4.2.0", - "q": "1.5.1", - "semver": "7.6.3", - "shelljs": "0.8.5", - "simple-git": "3.25.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "2.0.2", - "underscore": "1.13.6", - "uuid": "10.0.0", - "yaml-language-server": "1.15.1-f039273.0" - }, - "devDependencies": { - "@types/fs-extra": "11.0.4", - "@types/glob": "8.1.0", - "@types/js-yaml": "4.0.9", - "@types/mustache": "4.2.5", - "@types/node": "20.14.12", - "@types/q": "1.5.8", - "@types/underscore": "1.11.15", - "ajv": "8.17.1", - "assert": "2.1.0", - "chai": "5.1.1", - "glob": "11.0.0", - "nock": "14.0.0-beta.8", - "typescript-tslint-plugin": "0.5.5" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ], - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" -} + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "version": "1.2.3", + "publisher": "ms-vscode-deploy-azure", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/vscode-deploy-azure" + }, + "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", + "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", + "license": "MIT", + "icon": "assets/deployToAzure.png", + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "engines": { + "vscode": "^1.32.0" + }, + "categories": [ + "Programming Languages", + "Formatters", + "Azure" + ], + "tags": [ + "azure-pipelines", + "Azure Pipelines", + "Deploy to Azure", + "YAML" + ], + "keywords": [ + "YAML", + "Azure Pipelines", + "continuous integration", + "CI/CD" + ], + "activationEvents": [ + "*" + ], + "main": "./out/extension", + "contributes": { + "languages": [ + { + "id": "yaml", + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ] + } + ], + "grammars": [ + { + "language": "yaml", + "scopeName": "source.yaml", + "path": "./syntaxes/yaml.tmLanguage.json" + } + ], + "commands": [ + { + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline", + "category": "Deploy to Azure" + }, + { + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline", + "category": "Deploy to Azure" + } + ], + "menus": { + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ], + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ] + }, + "configuration": { + "title": "Deploy to Azure", + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "type": "boolean", + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "type": "boolean", + "default": true, + "description": "Use GitHub for creating new repository" + } + } + } + }, + "scripts": { + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./ && node copyStaticFiles.js", + "watch": "node copyStaticFiles.js && tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install", + "pretest": "npm run compile", + "test": "node ./out/configure/test/runTest.js" + }, + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mocha": "^7.0.2", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "mocha": "^7.1.2", + "nock": "^13.0.2", + "ts-node": "7.0.1", + "tslint": "5.8.0", + "tslint-microsoft-contrib": "^6.2.0", + "typescript": "3.3.1", + "typescript-tslint-plugin": "^0.5.5", + "vscode": "1.1.37", + "vscode-azureextensiondev": "^0.3.1", + "vscode-test": "^1.3.0" + }, + "dependencies": { + "azure-arm-resource": "7.3.0", + "azure-arm-website": "5.7.0", + "azureintegration-repoanalysis-client-internal": "^1.0.0", + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "vscode-azureextensionui": "0.26.3", + "vscode-extension-telemetry": "0.0.18", + "vscode-languageclient": "^5.2.1", + "vscode-nls": "3.2.4", + "vscode-uri": "1.0.6", + "yaml-language-server": "^0.8.0" + }, + "extensionDependencies": [ + "ms-vscode.azure-account" + ] +} \ No newline at end of file From d55ac0cb8eefc0b25a16de741aa969afcd36bd4e Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 25 Jul 2024 23:01:57 +0300 Subject: [PATCH 73/96] --- .github/FUNDING.yml | 1 - package.json | 283 ++++++++++++++++++-------------------------- 2 files changed, 116 insertions(+), 168 deletions(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 12f5195d..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -open_collective: code-editor-land diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} From 5285f9e4d46e91bf959cf1d1233f378144cc69e6 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 27 Jul 2024 20:09:39 +0300 Subject: [PATCH 74/96] --- CHANGELOG.md | 92 ++++++++++++++++++++++++++++++++++------------ CODE_OF_CONDUCT.md | 10 +++-- CONTRIBUTING.md | 23 +++++++----- README.md | 42 +++++++++++++++------ ReleaseProcess.md | 22 +++++++---- SECURITY.md | 54 +++++++++++++++++++-------- copyStaticFiles.js | 46 ++++++++++++----------- package.json | 24 ++++++------ tsconfig.json | 89 +++++++++++++++++++++----------------------- tslint.json | 16 ++------ 10 files changed, 252 insertions(+), 166 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a95af5f..37e42ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,78 +1,122 @@ # Change Log -All notable changes to the Deploy to Azure extension will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/). Versioning follows an internal Azure DevOps format that is not compatible with SemVer. +All notable changes to the Deploy to Azure extension will be documented in this +file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/). +Versioning follows an internal Azure DevOps format that is not compatible with +SemVer. ## 1.2.3 + ### Updated -- Moved Simple web app and python linux web app to use remote provisioning. -- Bug fixes -- Removed app id uris being set through the `identifierUris` field while creating the aad app + +- Moved Simple web app and python linux web app to use remote provisioning. +- Bug fixes +- Removed app id uris being set through the `identifierUris` field while + creating the aad app ## 1.2.2 + ### Updated -- Fixed azure pipeline support for Github repository. -- Updated Github PAT permissions needed for workflow commit + +- Fixed azure pipeline support for Github repository. +- Updated Github PAT permissions needed for workflow commit ## 1.2.1 + ### Updated -- Added support for configuring Pipeline remotely in case of .Net and .Net Core deployments to Web Apps. + +- Added support for configuring Pipeline remotely in case of .Net and .Net + Core deployments to Web Apps. ## 1.2.0 + ### Added -- Integrated with [Azure Kubernetes Service extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-aks-tools) to support configure ci/cd on right click of a cluster. + +- Integrated with + [Azure Kubernetes Service extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-aks-tools) + to support configure ci/cd on right click of a cluster. ## 1.1.5 + ### Added -- Added remote configurer for Github Node WebApp. + +- Added remote configurer for Github Node WebApp. ## 1.1.4 + ### Added -- Added remote configurer for Github AKS workflow. + +- Added remote configurer for Github AKS workflow. ## 1.1.3 + ### Added -- Fixed bugs. + +- Fixed bugs. ## 1.1.2 + ### Added -- Fixed session undefined bug. + +- Fixed session undefined bug. ## 1.1.1 + ### Added -- Improved telemetry for better insights. + +- Improved telemetry for better insights. ## 1.1.0 + ### Added -- If not a remote repo, have a provision of creating github repo. -- Added support for selecting the working directory if multiple applications are there to deploy. + +- If not a remote repo, have a provision of creating github repo. +- Added support for selecting the working directory if multiple applications + are there to deploy. ## 1.0.6 + ### Added -- Added telemetry for better insights. + +- Added telemetry for better insights. ## 1.0.5 + ### Added -- Added validations on auto generated GitHub secret names. + +- Added validations on auto generated GitHub secret names. ## 1.0.4 + ### Added -- Added support for Repository Analysis for GitHub repositories. + +- Added support for Repository Analysis for GitHub repositories. ## 1.0.3 + ### Added -- Update README.md. + +- Update README.md. ## 1.0.2 + ### Added -- Configure CI/CD for Github Workflow for Github Repositories. + +- Configure CI/CD for Github Workflow for Github Repositories. ## 1.0.1 + ### Added -- Merged template view for Windows and Linux WebApps. +- Merged template view for Windows and Linux WebApps. ## 1.0.0 + ### Added -- Initial release -- "Configure CI/CD Pipeline" option in Command Palette (Ctrl+Shift+P) and File Explorer. This will configure a continuous integration (CI) and deployment (CD) pipeline to Azure Linux Web App and Function App. + +- Initial release +- "Configure CI/CD Pipeline" option in Command Palette (Ctrl+Shift+P) and File + Explorer. This will configure a continuous integration (CI) and deployment + (CD) pipeline to Azure Linux Web App and Function App. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c72a5749..e16c86f4 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,9 +1,11 @@ # Microsoft Open Source Code of Conduct -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). Resources: -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with + questions or concerns diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54cdd168..2ece56d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,18 @@ # Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.microsoft.com. +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. For +details, visit https://cla.microsoft.com. -When you submit a pull request, a CLA-bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only need +to do this once across all repos using our CLA. -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. diff --git a/README.md b/README.md index 02d85b8b..48aaa1a7 100644 --- a/README.md +++ b/README.md @@ -4,35 +4,52 @@ [Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) - # 📢 ⛔ ATTENTION!! - Deprecation notice -This extension is being deprecated and will not be supported. Please see details [here](https://github.com/microsoft/vscode-deploy-azure/issues/239). - ----------------- +This extension is being deprecated and will not be supported. Please see details +[here](https://github.com/microsoft/vscode-deploy-azure/issues/239). +--- -This Visual Studio Code extension helps you set up continuous build and deployment for Azure App Service or for Azure Kubernetes Service without leaving Visual Studio Code. +This Visual Studio Code extension helps you set up continuous build and +deployment for Azure App Service or for Azure Kubernetes Service without leaving +Visual Studio Code. ![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) -To set up a pipeline, choose *Deploy to Azure: Configure CI/CD Pipeline* from the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. The guided workflow will generate a starter YAML file defining the build and deploy process. +To set up a pipeline, choose _Deploy to Azure: Configure CI/CD Pipeline_ from +the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. +The guided workflow will generate a starter YAML file defining the build and +deploy process. -You can customize the pipeline using all the features offered by [Azure Pipelines](https://azure.com/pipelines) and [GitHub Actions.](https://github.com/features/actions/) +You can customize the pipeline using all the features offered by +[Azure Pipelines](https://azure.com/pipelines) and +[GitHub Actions.](https://github.com/features/actions/) -Once the setup is completed, an automatic CI/CD trigger will fire for every code push. To set this up, if you have using GitHub as the repository the extension will ask for a GitHub PAT with *repo* and will configure GitHub Actions. +Once the setup is completed, an automatic CI/CD trigger will fire for every code +push. To set this up, if you have using GitHub as the repository the extension +will ask for a GitHub PAT with _repo_ and will configure GitHub Actions. ![GitHub PAT scope](ghpatpermissions.JPG) -You can refer to our [tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) for more details on the extension. +You can refer to our +[tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) +for more details on the extension. ## Telemetry -Visual Studio Code collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) to learn more. If you don’t wish to send usage data to Microsoft, you can set the `telemetry.enableTelemetry` setting to `false`. Learn more in our [FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). +Visual Studio Code collects usage data and sends it to Microsoft to help improve +our products and services. Read our +[privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) +to learn more. If you don’t wish to send usage data to Microsoft, you can set +the `telemetry.enableTelemetry` setting to `false`. Learn more in our +[FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). ## Troubleshooting failures -- **Failed to determine Azure Repo details from remote url**: If you're configuring a pipeline for a Git repository backed by Azure Repos, ensure that it has a remote pointing to a valid Azure Repos Git repo URL. +- **Failed to determine Azure Repo details from remote url**: If you're + configuring a pipeline for a Git repository backed by Azure Repos, ensure + that it has a remote pointing to a valid Azure Repos Git repo URL. # Contributing @@ -42,6 +59,7 @@ For TSLint to work in VSCode, run `npm install` and restart VSCode. # Testing framework -For adding test, create test files with extension `.test.ts` inside src/configure/test/suite. +For adding test, create test files with extension `.test.ts` inside +src/configure/test/suite. For running all the tests, use the command `npm test`. diff --git a/ReleaseProcess.md b/ReleaseProcess.md index 2e316cd9..3e429d7f 100644 --- a/ReleaseProcess.md +++ b/ReleaseProcess.md @@ -1,9 +1,17 @@ **Process for releasing a new version of VSCode extension - Deploy to Azure** -1. Update the new version in package.json and package-lock.json -2. Add concise description of the changes in the new version in ChangeLog.md and make changes in README.(if required). -3. Create a release branch for every major version update. Example, for version v1,v2,v3, create new branch : releases/v1, releases/v2, releases/v3. -4. Run the [pipeline](https://dev.azure.com/mseng/AzureDevOps/_build?definitionId=9571&_a=summary) with the release branch created. -5. Download the artifacts and get the [BVT testing](https://drive.google.com/file/d/1vLZ1I-LObjnV-6L3CPOSll1gbH4TJwA-/view?usp=sharing) done using the corresponding Vsix with the vendor team. -6. Create a tag for the corresponding version, using [Draft a new release](https://github.com/microsoft/vscode-deploy-azure/releases). -7. Upload the VSIX at the [marketplace](https://marketplace.visualstudio.com/manage/publishers/ms-vscode-deploy-azure?noPrompt=true). +1. Update the new version in package.json and package-lock.json +2. Add concise description of the changes in the new version in ChangeLog.md and + make changes in README.(if required). +3. Create a release branch for every major version update. Example, for version + v1,v2,v3, create new branch : releases/v1, releases/v2, releases/v3. +4. Run the + [pipeline](https://dev.azure.com/mseng/AzureDevOps/_build?definitionId=9571&_a=summary) + with the release branch created. +5. Download the artifacts and get the + [BVT testing](https://drive.google.com/file/d/1vLZ1I-LObjnV-6L3CPOSll1gbH4TJwA-/view?usp=sharing) + done using the corresponding Vsix with the vendor team. +6. Create a tag for the corresponding version, using + [Draft a new release](https://github.com/microsoft/vscode-deploy-azure/releases). +7. Upload the VSIX at the + [marketplace](https://marketplace.visualstudio.com/manage/publishers/ms-vscode-deploy-azure?noPrompt=true). diff --git a/SECURITY.md b/SECURITY.md index 7ab49eb8..876f70bf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,33 +2,54 @@ ## Security -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. +Microsoft takes the security of our software products and services seriously, +which includes all source code repositories managed through our GitHub +organizations, which include [Microsoft](https://github.com/Microsoft), +[Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), +[AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and +[our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned +repository that meets Microsoft's +[Microsoft's definition of a security vulnerability]() +of a security vulnerability, please report it to us as described below. ## Reporting Security Issues **Please do not report security vulnerabilities through public GitHub issues.** -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). +Instead, please report them to the Microsoft Security Response Center (MSRC) at +[https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). +If you prefer to submit without logging in, send email to +[secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your +message with our PGP key; please download it from the the +[Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). +You should receive a response within 24 hours. If for some reason you do not, +please follow up via email to ensure we received your original message. +Additional information can be found at +[microsoft.com/msrc](https://www.microsoft.com/msrc). -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: +Please include the requested information listed below (as much as you can +provide) to help us better understand the nature and scope of the possible +issue: - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, + etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. +If you are reporting for a bug bounty, more complete reports can contribute to a +higher bounty award. Please visit our +[Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more +details about our active programs. ## Preferred Languages @@ -36,6 +57,7 @@ We prefer all communications to be in English. ## Policy -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). +Microsoft follows the principle of +[Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). diff --git a/copyStaticFiles.js b/copyStaticFiles.js index 029f7ab4..f2c88990 100644 --- a/copyStaticFiles.js +++ b/copyStaticFiles.js @@ -1,34 +1,36 @@ "use strict"; -var path = require('path'); -var shell = require('shelljs'); +var path = require("path"); +var shell = require("shelljs"); //------------------------------------------------------------------------------ // shell functions //------------------------------------------------------------------------------ var shellAssert = function () { - var errMsg = shell.error(); - if (errMsg) { - throw new Error(errMsg); - } + var errMsg = shell.error(); + if (errMsg) { + throw new Error(errMsg); + } }; var cp = function (options, source, dest) { - if (dest) { - shell.cp(options, source, dest); - } - else { - shell.cp(options, source); - } - shellAssert(); + if (dest) { + shell.cp(options, source, dest); + } else { + shell.cp(options, source); + } + shellAssert(); }; var mkdir = function (options, target) { - if (target) { - shell.mkdir(options, target); - } - else { - shell.mkdir(options); - } - shellAssert(); + if (target) { + shell.mkdir(options, target); + } else { + shell.mkdir(options); + } + shellAssert(); }; -mkdir("-p", path.join(__dirname, 'out/configure/templates')); -cp("-Rf", path.join(__dirname, 'src/configure/templates/*'), path.join(__dirname, 'out/configure/templates')); +mkdir("-p", path.join(__dirname, "out/configure/templates")); +cp( + "-Rf", + path.join(__dirname, "src/configure/templates/*"), + path.join(__dirname, "out/configure/templates"), +); //# sourceMappingURL=copyStaticFiles.js.map diff --git a/package.json b/package.json index 64e0e50c..4e145024 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, "contributes": { "commands": [ { @@ -69,6 +72,9 @@ ] } }, + "activationEvents": [ + "*" + ], "dependencies": { "fs-extra": "^9.0.1", "js-yaml": "^3.13.1", @@ -84,7 +90,6 @@ "uuid": "^3.3.2", "yaml-language-server": "^0.8.0" }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "4.0.5", "@types/glob": "^7.1.1", @@ -100,18 +105,13 @@ "nock": "^13.0.2", "typescript-tslint-plugin": "^0.5.5" }, - "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], + "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "icon": "assets/deployToAzure.png", - "main": "./out/extension", - "name": "azure-deploy", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - } + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } diff --git a/tsconfig.json b/tsconfig.json index 8b117581..f37a4f03 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,39 +1,39 @@ { - "compilerOptions": { - /* Parse in strict mode and emit "use strict" for each source file. */ - "alwaysStrict": true, + "compilerOptions": { + /* Parse in strict mode and emit "use strict" for each source file. */ + "alwaysStrict": true, - /* List of library files to be included in the compilation. */ - "lib": [ "es6" ], + /* List of library files to be included in the compilation. */ + "lib": ["es6"], - /* Specify module code generation. */ - "module": "commonjs", + /* Specify module code generation. */ + "module": "commonjs", - /* */ - "moduleResolution": "node", + /* */ + "moduleResolution": "node", - /* Report errors for fallthrough cases in switch statement. */ - "noFallthroughCasesInSwitch": true, + /* Report errors for fallthrough cases in switch statement. */ + "noFallthroughCasesInSwitch": true, - /* Report error when not all code paths in function return a value. */ - "noImplicitReturns": true, + /* Report error when not all code paths in function return a value. */ + "noImplicitReturns": true, - /* Report errors on unused locals. */ - "noUnusedLocals": true, + /* Report errors on unused locals. */ + "noUnusedLocals": true, - /* Report errors on unused parameters. */ - //"noUnusedParameters": true, + /* Report errors on unused parameters. */ + //"noUnusedParameters": true, - /* Redirect output structure to the directory. */ - "outDir": "out", + /* Redirect output structure to the directory. */ + "outDir": "out", - /* Specifies the root directory of input files. Only use to control the output directory structure with --outDir. */ - "rootDir": "src", + /* Specifies the root directory of input files. Only use to control the output directory structure with --outDir. */ + "rootDir": "src", - /* Generates corresponding .map file. */ - "sourceMap": true, + /* Generates corresponding .map file. */ + "sourceMap": true, - /* Enable all strict type checking options. + /* Enable all strict type checking options. Enabling --strict enables --noImplicitAny, --noImplicitThis, @@ -42,27 +42,20 @@ --strictFunctionTypes --strictPropertyInitialization. */ - //"strict": true, - - /* Specify ECMAScript target version. */ - "target": "es6", - - /* */ - "allowJs": true, - - "plugins": [ - { - "name": "typescript-tslint-plugin" - } - ] - }, - "include": [ - "src/**/*", - "src/credentialstore/bin/win32/creds.exe" - ], - "exclude": [ - "node_modules", - ".vscode-test", - "tools/**" - ] -} \ No newline at end of file + //"strict": true, + + /* Specify ECMAScript target version. */ + "target": "es6", + + /* */ + "allowJs": true, + + "plugins": [ + { + "name": "typescript-tslint-plugin" + } + ] + }, + "include": ["src/**/*", "src/credentialstore/bin/win32/creds.exe"], + "exclude": ["node_modules", ".vscode-test", "tools/**"] +} diff --git a/tslint.json b/tslint.json index 26c084c5..ec10dc13 100644 --- a/tslint.json +++ b/tslint.json @@ -1,17 +1,12 @@ { - "rulesDirectory": [ - "node_modules/tslint-microsoft-contrib" - ], + "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], "rules": { "no-string-throw": true, "no-unused-expression": true, "no-duplicate-variable": true, "curly": true, "class-name": true, - "semicolon": [ - true, - "always" - ], + "semicolon": [true, "always"], "triple-equals": false, "no-banned-terms": true, "no-delete-expression": true, @@ -59,8 +54,5 @@ "non-literal-fs-path": false }, "defaultSeverity": "warning", - "extends": [ - "tslint-microsoft-contrib/recommended", - "tslint:recommended" - ] -} \ No newline at end of file + "extends": ["tslint-microsoft-contrib/recommended", "tslint:recommended"] +} From f103965e9dff1fa8f2ff6ddaf5c1f13b729437cc Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 27 Jul 2024 22:29:04 +0300 Subject: [PATCH 75/96] --- package.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 4e145024..f91d7dd1 100644 --- a/package.json +++ b/package.json @@ -76,34 +76,34 @@ "*" ], "dependencies": { - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", + "fs-extra": "9.0.1", + "js-yaml": "3.13.1", + "jsonpath-plus": "3.0.0", "mustache": "3.0.1", "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", + "semver": "7.3.2", + "shelljs": "0.3.0", + "simple-git": "1.110.0", "tweetsodium": "0.0.4", "typed-rest-client": "1.0.7", "underscore": "1.9.1", - "uuid": "^3.3.2", - "yaml-language-server": "^0.8.0" + "uuid": "3.3.2", + "yaml-language-server": "0.8.0" }, "devDependencies": { "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", + "@types/glob": "7.1.1", + "@types/js-yaml": "3.12.1", "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", + "@types/node": "7.0.43", "@types/q": "1.5.0", "@types/underscore": "1.8.9", - "ajv": "^6.9.1", + "ajv": "6.9.1", "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "nock": "^13.0.2", - "typescript-tslint-plugin": "^0.5.5" + "chai": "4.2.0", + "glob": "7.1.6", + "nock": "13.0.2", + "typescript-tslint-plugin": "0.5.5" }, "extensionDependencies": [ "ms-vscode.azure-account" From f09a5bb1c5749126a9ea4f2adf332da0eb1ff5d3 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 28 Jul 2024 00:51:04 +0300 Subject: [PATCH 76/96] --- Source/extension.ts | 119 +++++++++++++++++++++++----------- Source/logger.ts | 20 +++--- syntaxes/yaml.tmLanguage.json | 12 ++-- 3 files changed, 97 insertions(+), 54 deletions(-) diff --git a/Source/extension.ts b/Source/extension.ts index 56ed3cb5..d88c9654 100644 --- a/Source/extension.ts +++ b/Source/extension.ts @@ -1,87 +1,131 @@ /*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; +import * as path from "path"; +import * as vscode from "vscode"; +import { + AzureUserInput, + callWithTelemetryAndErrorHandling, + createTelemetryReporter, + IActionContext, + registerUIExtensionVariables, +} from "vscode-azureextensionui"; +import { + LanguageClient, + LanguageClientOptions, + ServerOptions, + TransportKind, +} from "vscode-languageclient"; +import { activateConfigurePipeline } from "./configure/activate"; +import { telemetryHelper } from "./configure/helper/telemetryHelper"; +import { extensionVariables } from "./configure/model/models"; +import { TelemetryKeys } from "./configure/resources/telemetryKeys"; +import { TracePoints } from "./configure/resources/tracePoints"; +import * as logger from "./logger"; -const Layer = 'Extension'; +const Layer = "Extension"; export async function activate(context: vscode.ExtensionContext) { extensionVariables.reporter = createTelemetryReporter(context); registerUiVariables(context); - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { + await callWithTelemetryAndErrorHandling( + "azuredeploy.activate", + async (activateContext: IActionContext) => { + activateContext.telemetry.properties.isActivationEvent = "true"; + telemetryHelper.initialize(activateContext, "activate"); + await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); + }, TelemetryKeys.ExtensionActivationDuration); + }, + ); startLanguageClient(context); - logger.log('Extension has been activated!', 'ExtensionActivated'); + logger.log("Extension has been activated!", "ExtensionActivated"); } function startLanguageClient(context: vscode.ExtensionContext) { try { // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); + let serverModule = context.asAbsolutePath( + path.join( + "node_modules", + "yaml-language-server", + "out", + "server", + "src", + "server.js", + ), + ); // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; + let debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] }; // If the extension is launched in debug mode then the debug server options are used // Otherwise the run options are used let serverOptions: ServerOptions = { run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } + debug: { + module: serverModule, + transport: TransportKind.ipc, + options: debugOptions, + }, }; // Options to control the scope of language client let clientOptions: LanguageClientOptions = { documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } + { + language: "yaml", + pattern: "**/.github/workflows/**", + scheme: "file", + }, ], synchronize: { // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], + configurationSection: [ + "yaml", + "http.proxy", + "http.proxyStrictSSL", + ], // Notify the server about file changes to YAML files contained in the workspace fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } + vscode.workspace.createFileSystemWatcher( + "**/*.?(e)y?(a)ml", + ), + ], + }, }; // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); + let client = new LanguageClient( + "yaml", + "YAML Support", + serverOptions, + clientOptions, + ); let disposable = client.start(); // Push the disposable to the context's subscriptions so that the // client can be deactivated on extension deactivation context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); + } catch (error) { + telemetryHelper.logError( + Layer, + TracePoints.LanguageClientActivationFailed, + error, + ); } } function registerUiVariables(context: vscode.ExtensionContext) { // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); + extensionVariables.outputChannel = + vscode.window.createOutputChannel("Deploy to Azure"); context.subscriptions.push(extensionVariables.outputChannel); extensionVariables.context = context; extensionVariables.ui = new AzureUserInput(context.globalState); @@ -89,5 +133,4 @@ function registerUiVariables(context: vscode.ExtensionContext) { } // this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file +export function deactivate() {} diff --git a/Source/logger.ts b/Source/logger.ts index 28a70627..ebf7068a 100644 --- a/Source/logger.ts +++ b/Source/logger.ts @@ -1,20 +1,20 @@ import { extensionVariables } from "./configure/model/models"; /*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + *--------------------------------------------------------------------------------------------*/ // TODO: How can we write this to disk too so that we can remotely debug issues? // TODO: Set env var or something to turn logging on/off? -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; +export function log(message: string, event?: string) { + let logMessage = `(${new Date().toLocaleString()}) `; - if (event) { - logMessage += `[${event}] `; - } + if (event) { + logMessage += `[${event}] `; + } - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); + logMessage += `${message}`; + extensionVariables.outputChannel.appendLine(logMessage); } diff --git a/syntaxes/yaml.tmLanguage.json b/syntaxes/yaml.tmLanguage.json index 90f562a3..c98b9811 100644 --- a/syntaxes/yaml.tmLanguage.json +++ b/syntaxes/yaml.tmLanguage.json @@ -211,7 +211,7 @@ "name": "support.type.tag-prefix.yaml" } }, - "match": "(?x)\n \\G\n (TAG)\n (?:[ \\t]+\n ((?:!(?:[0-9A-Za-z\\-]*!)?))\n (?:[ \\t]+ (\n ! (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;\/?:@&=+$,_.!~*'()\\[\\]] )*\n | (?![,!\\[\\]{}]) (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;\/?:@&=+$,_.!~*'()\\[\\]] )+\n )\n )?\n )?\n " + "match": "(?x)\n \\G\n (TAG)\n (?:[ \\t]+\n ((?:!(?:[0-9A-Za-z\\-]*!)?))\n (?:[ \\t]+ (\n ! (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )*\n | (?![,!\\[\\]{}]) (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+\n )\n )?\n )?\n " }, { "captures": { @@ -248,7 +248,7 @@ "name": "invalid.illegal.character.anchor.yaml" } }, - "match": "((\\*))([^\\s\\[\\]\/{\/},]+)([^\\s\\]},]\\S*)?" + "match": "((\\*))([^\\s\\[\\]/{/},]+)([^\\s\\]},]\\S*)?" }, "flow-collection": { "patterns": [ @@ -410,7 +410,7 @@ "name": "string.quoted.double.yaml", "patterns": [ { - "match": "\\\\([0abtnvfre \"\/\\\\N_Lp]|x\\d\\d|u\\d{4}|U\\d{8})", + "match": "\\\\([0abtnvfre \"/\\\\N_Lp]|x\\d\\d|u\\d{4}|U\\d{8})", "name": "constant.character.escape.yaml" }, { @@ -595,10 +595,10 @@ "name": "invalid.illegal.character.anchor.yaml" } }, - "match": "\\G((&))([^\\s\\[\\]\/{\/},]+)(\\S+)?" + "match": "\\G((&))([^\\s\\[\\]/{/},]+)(\\S+)?" }, { - "match": "(?x)\n \\G\n (?:\n ! < (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;\/?:@&=+$,_.!~*'()\\[\\]] )+ >\n | (?:!(?:[0-9A-Za-z\\-]*!)?) (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;\/?:@&=+$_.~*'()] )+\n | !\n )\n (?=\\ |\\t|$)\n ", + "match": "(?x)\n \\G\n (?:\n ! < (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+ >\n | (?:!(?:[0-9A-Za-z\\-]*!)?) (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$_.~*'()] )+\n | !\n )\n (?=\\ |\\t|$)\n ", "name": "storage.type.tag-handle.yaml" }, { @@ -618,4 +618,4 @@ ] } } -} \ No newline at end of file +} From 22ea70d9d15947107e129ed07a838172a1205579 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 28 Jul 2024 01:45:46 +0300 Subject: [PATCH 77/96] --- CODE_OF_CONDUCT.md | 22 ++++---- LICENSE | 42 +++++++-------- README.md | 130 ++++++++++++++++++++++----------------------- SECURITY.md | 126 +++++++++++++++++++++---------------------- 4 files changed, 160 insertions(+), 160 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e16c86f4..bb1fb9ac 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,11 +1,11 @@ -# Microsoft Open Source Code of Conduct - -This project has adopted the -[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with - questions or concerns +# Microsoft Open Source Code of Conduct + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). + +Resources: + +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with + questions or concerns diff --git a/LICENSE b/LICENSE index 3d8b93bc..9e841e7a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/README.md b/README.md index 48aaa1a7..b2c7065c 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,65 @@ -[![Build Status](https://dev.azure.com/mseng/AzureDevOps/_apis/build/status/vscode-deploy-azure-CI)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=9436) - -# Deploy to Azure from Visual Studio Code - -[Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) - -# 📢 ⛔ ATTENTION!! - Deprecation notice - -This extension is being deprecated and will not be supported. Please see details -[here](https://github.com/microsoft/vscode-deploy-azure/issues/239). - ---- - -This Visual Studio Code extension helps you set up continuous build and -deployment for Azure App Service or for Azure Kubernetes Service without leaving -Visual Studio Code. - -![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) - -To set up a pipeline, choose _Deploy to Azure: Configure CI/CD Pipeline_ from -the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. -The guided workflow will generate a starter YAML file defining the build and -deploy process. - -You can customize the pipeline using all the features offered by -[Azure Pipelines](https://azure.com/pipelines) and -[GitHub Actions.](https://github.com/features/actions/) - -Once the setup is completed, an automatic CI/CD trigger will fire for every code -push. To set this up, if you have using GitHub as the repository the extension -will ask for a GitHub PAT with _repo_ and will configure GitHub Actions. - -![GitHub PAT scope](ghpatpermissions.JPG) - -You can refer to our -[tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) -for more details on the extension. - -## Telemetry - -Visual Studio Code collects usage data and sends it to Microsoft to help improve -our products and services. Read our -[privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) -to learn more. If you don’t wish to send usage data to Microsoft, you can set -the `telemetry.enableTelemetry` setting to `false`. Learn more in our -[FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). - -## Troubleshooting failures - -- **Failed to determine Azure Repo details from remote url**: If you're - configuring a pipeline for a Git repository backed by Azure Repos, ensure - that it has a remote pointing to a valid Azure Repos Git repo URL. - -# Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to jump in! - -For TSLint to work in VSCode, run `npm install` and restart VSCode. - -# Testing framework - -For adding test, create test files with extension `.test.ts` inside -src/configure/test/suite. - -For running all the tests, use the command `npm test`. +[![Build Status](https://dev.azure.com/mseng/AzureDevOps/_apis/build/status/vscode-deploy-azure-CI)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=9436) + +# Deploy to Azure from Visual Studio Code + +[Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) + +# 📢 ⛔ ATTENTION!! - Deprecation notice + +This extension is being deprecated and will not be supported. Please see details +[here](https://github.com/microsoft/vscode-deploy-azure/issues/239). + +--- + +This Visual Studio Code extension helps you set up continuous build and +deployment for Azure App Service or for Azure Kubernetes Service without leaving +Visual Studio Code. + +![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) + +To set up a pipeline, choose _Deploy to Azure: Configure CI/CD Pipeline_ from +the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. +The guided workflow will generate a starter YAML file defining the build and +deploy process. + +You can customize the pipeline using all the features offered by +[Azure Pipelines](https://azure.com/pipelines) and +[GitHub Actions.](https://github.com/features/actions/) + +Once the setup is completed, an automatic CI/CD trigger will fire for every code +push. To set this up, if you have using GitHub as the repository the extension +will ask for a GitHub PAT with _repo_ and will configure GitHub Actions. + +![GitHub PAT scope](ghpatpermissions.JPG) + +You can refer to our +[tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) +for more details on the extension. + +## Telemetry + +Visual Studio Code collects usage data and sends it to Microsoft to help improve +our products and services. Read our +[privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) +to learn more. If you don’t wish to send usage data to Microsoft, you can set +the `telemetry.enableTelemetry` setting to `false`. Learn more in our +[FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). + +## Troubleshooting failures + +- **Failed to determine Azure Repo details from remote url**: If you're + configuring a pipeline for a Git repository backed by Azure Repos, ensure + that it has a remote pointing to a valid Azure Repos Git repo URL. + +# Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to jump in! + +For TSLint to work in VSCode, run `npm install` and restart VSCode. + +# Testing framework + +For adding test, create test files with extension `.test.ts` inside +src/configure/test/suite. + +For running all the tests, use the command `npm test`. diff --git a/SECURITY.md b/SECURITY.md index 876f70bf..4fe08faf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,63 +1,63 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, -which includes all source code repositories managed through our GitHub -organizations, which include [Microsoft](https://github.com/Microsoft), -[Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), -[AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and -[our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned -repository that meets Microsoft's -[Microsoft's definition of a security vulnerability]() -of a security vulnerability, please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at -[https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to -[secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your -message with our PGP key; please download it from the the -[Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, -please follow up via email to ensure we received your original message. -Additional information can be found at -[microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can -provide) to help us better understand the nature and scope of the possible -issue: - -- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, - etc.) -- Full paths of source file(s) related to the manifestation of the issue -- The location of the affected source code (tag/branch/commit or direct URL) -- Any special configuration required to reproduce the issue -- Step-by-step instructions to reproduce the issue -- Proof-of-concept or exploit code (if possible) -- Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a -higher bounty award. Please visit our -[Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more -details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of -[Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - + + +## Security + +Microsoft takes the security of our software products and services seriously, +which includes all source code repositories managed through our GitHub +organizations, which include [Microsoft](https://github.com/Microsoft), +[Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), +[AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and +[our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned +repository that meets Microsoft's +[Microsoft's definition of a security vulnerability]() +of a security vulnerability, please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at +[https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). + +If you prefer to submit without logging in, send email to +[secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your +message with our PGP key; please download it from the the +[Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). + +You should receive a response within 24 hours. If for some reason you do not, +please follow up via email to ensure we received your original message. +Additional information can be found at +[microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can +provide) to help us better understand the nature and scope of the possible +issue: + +- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, + etc.) +- Full paths of source file(s) related to the manifestation of the issue +- The location of the affected source code (tag/branch/commit or direct URL) +- Any special configuration required to reproduce the issue +- Step-by-step instructions to reproduce the issue +- Proof-of-concept or exploit code (if possible) +- Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a +higher bounty award. Please visit our +[Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more +details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of +[Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). + + From 27cc767f406735c41657f4e7780600652c5bc627 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 28 Jul 2024 16:22:26 +0300 Subject: [PATCH 78/96] --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index f91d7dd1..95a0bf4c 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,8 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - }, + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "contributes": { "commands": [ { @@ -72,9 +69,6 @@ ] } }, - "activationEvents": [ - "*" - ], "dependencies": { "fs-extra": "9.0.1", "js-yaml": "3.13.1", @@ -90,6 +84,7 @@ "uuid": "3.3.2", "yaml-language-server": "0.8.0" }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "4.0.5", "@types/glob": "7.1.1", @@ -105,13 +100,18 @@ "nock": "13.0.2", "typescript-tslint-plugin": "0.5.5" }, + "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } } From 558d5da9bc0674bb5e14c1564d6e7958e1d6186b Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 2 Aug 2024 02:43:33 +0300 Subject: [PATCH 79/96] --- package.json | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 95a0bf4c..4e14eba9 100644 --- a/package.json +++ b/package.json @@ -70,35 +70,35 @@ } }, "dependencies": { - "fs-extra": "9.0.1", - "js-yaml": "3.13.1", - "jsonpath-plus": "3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "7.3.2", - "shelljs": "0.3.0", - "simple-git": "1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "3.3.2", - "yaml-language-server": "0.8.0" + "fs-extra": "11.2.0", + "js-yaml": "4.1.0", + "jsonpath-plus": "9.0.0", + "mustache": "4.2.0", + "q": "2.0.3", + "semver": "7.6.3", + "shelljs": "0.8.5", + "simple-git": "3.25.0", + "tweetsodium": "0.0.6", + "typed-rest-client": "2.0.2", + "underscore": "1.13.7", + "uuid": "10.0.0", + "yaml-language-server": "1.15.1-f039273.0" }, "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "7.1.1", - "@types/js-yaml": "3.12.1", - "@types/mustache": "0.8.32", - "@types/node": "7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "6.9.1", - "assert": "1.4.1", - "chai": "4.2.0", - "glob": "7.1.6", - "nock": "13.0.2", - "typescript-tslint-plugin": "0.5.5" + "@types/fs-extra": "11.0.4", + "@types/glob": "8.1.0", + "@types/js-yaml": "4.0.9", + "@types/mustache": "4.2.5", + "@types/node": "22.0.2", + "@types/q": "1.5.8", + "@types/underscore": "1.11.15", + "ajv": "8.17.1", + "assert": "2.1.0", + "chai": "5.1.1", + "glob": "11.0.0", + "nock": "14.0.0-beta.9", + "typescript-tslint-plugin": "1.0.2" }, "displayName": "Deploy to Azure", "extensionDependencies": [ From 5adbe548e566e1416805e033065326792b894441 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 8 Aug 2024 09:20:17 +0300 Subject: [PATCH 80/96] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4e14eba9..345305bd 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "22.0.2", + "@types/node": "22.1.0", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.17.1", From e8385f79b8ee9fd86905f3db4e3e70c6568cc2dc Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 19 Aug 2024 00:19:29 +0300 Subject: [PATCH 81/96] --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 345305bd..2de4f10a 100644 --- a/package.json +++ b/package.json @@ -90,14 +90,14 @@ "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "22.1.0", + "@types/node": "22.4.0", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.17.1", "assert": "2.1.0", "chai": "5.1.1", "glob": "11.0.0", - "nock": "14.0.0-beta.9", + "nock": "14.0.0-beta.11", "typescript-tslint-plugin": "1.0.2" }, "displayName": "Deploy to Azure", From a7948fc0f79d6421608ca26d15d674cfe5967f89 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 22 Aug 2024 03:01:42 +0300 Subject: [PATCH 82/96] --- .github/dependabot.yml | 14 ++++++ .github/workflows/Dependabot.yml | 45 +++++++++++++++++ .github/workflows/GitHub.yml | 58 ++++++++++++++++++++++ .github/workflows/Node.yml | 85 ++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml create mode 100644 .github/workflows/GitHub.yml create mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..387fece7 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml new file mode 100644 index 00000000..7b1e399c --- /dev/null +++ b/.github/workflows/GitHub.yml @@ -0,0 +1,58 @@ +name: GitHub + +concurrency: + group: GitHub-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + issues: write + pull-requests: write + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + Assign: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 + + steps: + - uses: pozil/auto-assign-issue@v2.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: NikolaRHristov + numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml new file mode 100644 index 00000000..dfdd1814 --- /dev/null +++ b/.github/workflows/Node.yml @@ -0,0 +1,85 @@ +name: Node + +concurrency: + group: Node-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + push: + branches: [Current] + pull_request: + branches: [Current] + workflow_call: + +jobs: + Pre-Publish: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 + + strategy: + matrix: + node-version: [18, 19, 20] + + steps: + - uses: actions/checkout@v4.1.7 + + - uses: pnpm/action-setup@v4.0.0 + with: + version: 9.3.0 + run_install: | + - recursive: true + args: [ + --link-workspace-packages=true, + --lockfile-only, + --prefer-frozen-lockfile=false, + --shamefully-hoist=false, + --shared-workspace-lockfile=true, + --strict-peer-dependencies=false, + --unsafe-perm=true + ] + + - uses: actions/setup-node@v4.0.3 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: ./pnpm-lock.yaml + + - run: pnpm install + working-directory: . From 4c3f2e3257ec8690d1406bb7015df36e07d68e75 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Thu, 22 Aug 2024 06:10:41 +0300 Subject: [PATCH 83/96] --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 2de4f10a..c346e733 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "name": "azure-deploy", + "displayName": "Deploy to Azure", + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "main": "./out/extension", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + }, "contributes": { "commands": [ { @@ -69,6 +72,9 @@ ] } }, + "activationEvents": [ + "*" + ], "dependencies": { "fs-extra": "11.2.0", "js-yaml": "4.1.0", @@ -84,7 +90,6 @@ "uuid": "10.0.0", "yaml-language-server": "1.15.1-f039273.0" }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -100,18 +105,13 @@ "nock": "14.0.0-beta.11", "typescript-tslint-plugin": "1.0.2" }, - "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], + "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "icon": "assets/deployToAzure.png", - "main": "./out/extension", - "name": "azure-deploy", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - } + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" } From 3c79dfac815440db6998e3aa594fa0a79087931e Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sat, 24 Aug 2024 10:23:02 +0300 Subject: [PATCH 84/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 131 files changed, 116 insertions(+), 9128 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From 4336901464bb4c6c1c464f0c06f8ce9b3cf70478 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 25 Aug 2024 03:03:11 +0300 Subject: [PATCH 85/96] --- .github/dependabot.yml | 14 ------ .github/workflows/Dependabot.yml | 45 ----------------- .github/workflows/GitHub.yml | 58 ---------------------- .github/workflows/Node.yml | 85 -------------------------------- package.json | 24 ++++----- 5 files changed, 12 insertions(+), 214 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml delete mode 100644 .github/workflows/GitHub.yml delete mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index 387fece7..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml deleted file mode 100644 index 7b1e399c..00000000 --- a/.github/workflows/GitHub.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: GitHub - -concurrency: - group: GitHub-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - issues: write - pull-requests: write - -on: - issues: - types: [opened] - pull_request: - types: [opened] - -jobs: - Assign: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - steps: - - uses: pozil/auto-assign-issue@v2.0.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: NikolaRHristov - numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml deleted file mode 100644 index dfdd1814..00000000 --- a/.github/workflows/Node.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Node - -concurrency: - group: Node-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - push: - branches: [Current] - pull_request: - branches: [Current] - workflow_call: - -jobs: - Pre-Publish: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - strategy: - matrix: - node-version: [18, 19, 20] - - steps: - - uses: actions/checkout@v4.1.7 - - - uses: pnpm/action-setup@v4.0.0 - with: - version: 9.3.0 - run_install: | - - recursive: true - args: [ - --link-workspace-packages=true, - --lockfile-only, - --prefer-frozen-lockfile=false, - --shamefully-hoist=false, - --shared-workspace-lockfile=true, - --strict-peer-dependencies=false, - --unsafe-perm=true - ] - - - uses: actions/setup-node@v4.0.3 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./pnpm-lock.yaml - - - run: pnpm install - working-directory: . diff --git a/package.json b/package.json index c346e733..2de4f10a 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,8 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "main": "./out/extension", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - }, + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "contributes": { "commands": [ { @@ -72,9 +69,6 @@ ] } }, - "activationEvents": [ - "*" - ], "dependencies": { "fs-extra": "11.2.0", "js-yaml": "4.1.0", @@ -90,6 +84,7 @@ "uuid": "10.0.0", "yaml-language-server": "1.15.1-f039273.0" }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { "@types/fs-extra": "11.0.4", "@types/glob": "8.1.0", @@ -105,13 +100,18 @@ "nock": "14.0.0-beta.11", "typescript-tslint-plugin": "1.0.2" }, + "displayName": "Deploy to Azure", "extensionDependencies": [ "ms-vscode.azure-account" ], - "icon": "assets/deployToAzure.png", "galleryBanner": { "color": "#D4DCEC", "theme": "light" }, - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217" + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } } From fe7ff7a688d20c8c99fcb776c955fe50efab287d Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Sun, 25 Aug 2024 06:37:22 +0300 Subject: [PATCH 86/96] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2de4f10a..5d5bc2e8 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "@types/glob": "8.1.0", "@types/js-yaml": "4.0.9", "@types/mustache": "4.2.5", - "@types/node": "22.4.0", + "@types/node": "22.5.0", "@types/q": "1.5.8", "@types/underscore": "1.11.15", "ajv": "8.17.1", From 92e4e5ea1e145265887a8b28aebb86789c1453c9 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Mon, 26 Aug 2024 08:48:15 +0300 Subject: [PATCH 87/96] --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5d5bc2e8..40aa86a6 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "typed-rest-client": "2.0.2", "underscore": "1.13.7", "uuid": "10.0.0", - "yaml-language-server": "1.15.1-f039273.0" + "yaml-language-server": "1.15.0" }, "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", "devDependencies": { @@ -97,7 +97,7 @@ "assert": "2.1.0", "chai": "5.1.1", "glob": "11.0.0", - "nock": "14.0.0-beta.11", + "nock": "13.5.5", "typescript-tslint-plugin": "1.0.2" }, "displayName": "Deploy to Azure", From 1fe9c13dad1f7d53b7b61429f5bef3b6686e6183 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 27 Aug 2024 07:10:26 +0300 Subject: [PATCH 88/96] --- {Source => src}/configure/activate.ts | 0 {Source => src}/configure/browse.ts | 0 {Source => src}/configure/clients/IProvisioningServiceClient.ts | 0 {Source => src}/configure/clients/ITemplateServiceClient.ts | 0 {Source => src}/configure/clients/ProvisioningServiceClient.ts | 0 {Source => src}/configure/clients/TemplateServiceClientFactory.ts | 0 {Source => src}/configure/clients/azure/appServiceClient.ts | 0 {Source => src}/configure/clients/azure/armRestClient.ts | 0 {Source => src}/configure/clients/azure/azureResourceClient.ts | 0 {Source => src}/configure/clients/devOps/azureDevOpsClient.ts | 0 .../configure/clients/devOps/serviceConnectionClient.ts | 0 {Source => src}/configure/clients/github/TemplateServiceClient.ts | 0 {Source => src}/configure/clients/github/githubClient.ts | 0 {Source => src}/configure/clients/modaRepositoryAnalysisClient.ts | 0 .../configure/clients/portalExtensionRepositoryAnalysisClient.ts | 0 .../configure/clients/provisioningServiceClientFactory.ts | 0 {Source => src}/configure/clients/repositoryAnalyisClient.ts | 0 {Source => src}/configure/clients/restClient.ts | 0 {Source => src}/configure/configure.ts | 0 {Source => src}/configure/configurers/AksAzureResourceSelector.ts | 0 {Source => src}/configure/configurers/IAzureResourceSelector.ts | 0 {Source => src}/configure/configurers/IProvisioningConfigurer.ts | 0 {Source => src}/configure/configurers/ResourceSelectorFactory.ts | 0 .../configure/configurers/WebAppAzureResourceSelector.ts | 0 {Source => src}/configure/configurers/azurePipelineConfigurer.ts | 0 {Source => src}/configure/configurers/configurerBase.ts | 0 {Source => src}/configure/configurers/configurerFactory.ts | 0 .../configure/configurers/localGithubWorkflowConfigurer.ts | 0 {Source => src}/configure/configurers/provisioningConfigurer.ts | 0 .../configure/configurers/remoteGitHubWorkflowConfigurer.ts | 0 {Source => src}/configure/helper/AssetHandler.ts | 0 {Source => src}/configure/helper/DataSourceHandler.ts | 0 {Source => src}/configure/helper/LocalGitRepoHelper.ts | 0 {Source => src}/configure/helper/azureSessionHelper.ts | 0 {Source => src}/configure/helper/commonHelper.ts | 0 {Source => src}/configure/helper/controlProvider.ts | 0 {Source => src}/configure/helper/devOps/azureDevOpsHelper.ts | 0 .../configure/helper/devOps/serviceConnectionHelper.ts | 0 {Source => src}/configure/helper/gitHubHelper.ts | 0 {Source => src}/configure/helper/graphHelper.ts | 0 {Source => src}/configure/helper/mustacheHelper.ts | 0 {Source => src}/configure/helper/remoteServiceUrlHelper.ts | 0 {Source => src}/configure/helper/repoAnalysisHelper.ts | 0 {Source => src}/configure/helper/sodium/SodiumLibHelper.ts | 0 {Source => src}/configure/helper/sodium/sodium.d.ts | 0 {Source => src}/configure/helper/telemetryHelper.ts | 0 {Source => src}/configure/helper/templateHelper.ts | 0 {Source => src}/configure/helper/templateParameterHelper.ts | 0 {Source => src}/configure/model/Contracts.ts | 0 {Source => src}/configure/model/azureDevOps.ts | 0 {Source => src}/configure/model/models.ts | 0 {Source => src}/configure/model/provisioningConfiguration.ts | 0 {Source => src}/configure/model/templateModels.ts | 0 {Source => src}/configure/resources/constants.ts | 0 {Source => src}/configure/resources/messages.ts | 0 {Source => src}/configure/resources/telemetryKeys.ts | 0 {Source => src}/configure/resources/tracePoints.ts | 0 {Source => src}/configure/templateInputHelper/InputControl.ts | 0 .../configure/templateInputHelper/InputControlProvider.ts | 0 .../templateInputHelper/RepoAnalysisSettingInputProvider.ts | 0 .../templateInputHelper/utilities/DataSourceExpression.ts | 0 .../configure/templateInputHelper/utilities/DataSourceUtility.ts | 0 .../templateInputHelper/utilities/InputControlUtility.ts | 0 .../configure/templateInputHelper/utilities/VisibilityHelper.ts | 0 .../templateInputHelper/utilities/validation/StaticValidator.ts | 0 .../azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml | 0 .../templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml | 0 .../azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml | 0 .../templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml | 0 .../configure/templates/azurePipelineTemplates/nodejs.yml | 0 .../templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml | 0 .../templates/azurePipelineTemplates/nodejsLinuxWebApp.yml | 0 .../templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml | 0 .../templates/azurePipelineTemplates/nodejsWithAngular.yml | 0 .../azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml | 0 .../templates/azurePipelineTemplates/nodejsWithGrunt.yml | 0 .../azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml | 0 .../configure/templates/azurePipelineTemplates/nodejsWithGulp.yml | 0 .../azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml | 0 .../templates/azurePipelineTemplates/nodejsWithWebpack.yml | 0 .../azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml | 0 .../configure/templates/azurePipelineTemplates/pythonDjango.yml | 0 .../templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml | 0 .../templates/azurePipelineTemplates/pythonLinuxWebApp.yml | 0 .../templates/azurePipelineTemplates/simpleLinuxWebApp.yml | 0 .../configure/templates/azurePipelineTemplates/simpleWebApp.yml | 0 {Source => src}/configure/templates/dependencies/deployment.yml | 0 {Source => src}/configure/templates/dependencies/ingress.yml | 0 .../configure/templates/dependencies/service-ingress.yml | 0 {Source => src}/configure/templates/dependencies/service.yml | 0 .../templates/githubWorkflowTemplates/AksWithReuseACR.yml | 0 .../templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml | 0 .../configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../templates/githubWorkflowTemplates/nodejsOnWindows.yml | 0 .../githubWorkflowTemplates/nodejsWindowsFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml | 0 .../githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml | 0 .../templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml | 0 .../templates/githubWorkflowTemplates/pythonLinuxWebApp.yml | 0 .../configure/templates/githubWorkflowTemplates/simpleWebApp.yml | 0 {Source => src}/configure/utilities/templateConverter.ts | 0 {Source => src}/configure/utilities/utilities.ts | 0 {Source => src}/configure/utilities/webAppNodeVersionConverter.ts | 0 {Source => src}/extension.ts | 0 {Source => src}/logger.ts | 0 111 files changed, 0 insertions(+), 0 deletions(-) rename {Source => src}/configure/activate.ts (100%) rename {Source => src}/configure/browse.ts (100%) rename {Source => src}/configure/clients/IProvisioningServiceClient.ts (100%) rename {Source => src}/configure/clients/ITemplateServiceClient.ts (100%) rename {Source => src}/configure/clients/ProvisioningServiceClient.ts (100%) rename {Source => src}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {Source => src}/configure/clients/azure/appServiceClient.ts (100%) rename {Source => src}/configure/clients/azure/armRestClient.ts (100%) rename {Source => src}/configure/clients/azure/azureResourceClient.ts (100%) rename {Source => src}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {Source => src}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {Source => src}/configure/clients/github/TemplateServiceClient.ts (100%) rename {Source => src}/configure/clients/github/githubClient.ts (100%) rename {Source => src}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {Source => src}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {Source => src}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {Source => src}/configure/clients/repositoryAnalyisClient.ts (100%) rename {Source => src}/configure/clients/restClient.ts (100%) rename {Source => src}/configure/configure.ts (100%) rename {Source => src}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {Source => src}/configure/configurers/IAzureResourceSelector.ts (100%) rename {Source => src}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {Source => src}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {Source => src}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {Source => src}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {Source => src}/configure/configurers/configurerBase.ts (100%) rename {Source => src}/configure/configurers/configurerFactory.ts (100%) rename {Source => src}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {Source => src}/configure/configurers/provisioningConfigurer.ts (100%) rename {Source => src}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {Source => src}/configure/helper/AssetHandler.ts (100%) rename {Source => src}/configure/helper/DataSourceHandler.ts (100%) rename {Source => src}/configure/helper/LocalGitRepoHelper.ts (100%) rename {Source => src}/configure/helper/azureSessionHelper.ts (100%) rename {Source => src}/configure/helper/commonHelper.ts (100%) rename {Source => src}/configure/helper/controlProvider.ts (100%) rename {Source => src}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {Source => src}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {Source => src}/configure/helper/gitHubHelper.ts (100%) rename {Source => src}/configure/helper/graphHelper.ts (100%) rename {Source => src}/configure/helper/mustacheHelper.ts (100%) rename {Source => src}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {Source => src}/configure/helper/repoAnalysisHelper.ts (100%) rename {Source => src}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {Source => src}/configure/helper/sodium/sodium.d.ts (100%) rename {Source => src}/configure/helper/telemetryHelper.ts (100%) rename {Source => src}/configure/helper/templateHelper.ts (100%) rename {Source => src}/configure/helper/templateParameterHelper.ts (100%) rename {Source => src}/configure/model/Contracts.ts (100%) rename {Source => src}/configure/model/azureDevOps.ts (100%) rename {Source => src}/configure/model/models.ts (100%) rename {Source => src}/configure/model/provisioningConfiguration.ts (100%) rename {Source => src}/configure/model/templateModels.ts (100%) rename {Source => src}/configure/resources/constants.ts (100%) rename {Source => src}/configure/resources/messages.ts (100%) rename {Source => src}/configure/resources/telemetryKeys.ts (100%) rename {Source => src}/configure/resources/tracePoints.ts (100%) rename {Source => src}/configure/templateInputHelper/InputControl.ts (100%) rename {Source => src}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {Source => src}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {Source => src}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {Source => src}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {Source => src}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {Source => src}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {Source => src}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {Source => src}/configure/templates/dependencies/deployment.yml (100%) rename {Source => src}/configure/templates/dependencies/ingress.yml (100%) rename {Source => src}/configure/templates/dependencies/service-ingress.yml (100%) rename {Source => src}/configure/templates/dependencies/service.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {Source => src}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {Source => src}/configure/utilities/templateConverter.ts (100%) rename {Source => src}/configure/utilities/utilities.ts (100%) rename {Source => src}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {Source => src}/extension.ts (100%) rename {Source => src}/logger.ts (100%) diff --git a/Source/configure/activate.ts b/src/configure/activate.ts similarity index 100% rename from Source/configure/activate.ts rename to src/configure/activate.ts diff --git a/Source/configure/browse.ts b/src/configure/browse.ts similarity index 100% rename from Source/configure/browse.ts rename to src/configure/browse.ts diff --git a/Source/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from Source/configure/clients/IProvisioningServiceClient.ts rename to src/configure/clients/IProvisioningServiceClient.ts diff --git a/Source/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from Source/configure/clients/ITemplateServiceClient.ts rename to src/configure/clients/ITemplateServiceClient.ts diff --git a/Source/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from Source/configure/clients/ProvisioningServiceClient.ts rename to src/configure/clients/ProvisioningServiceClient.ts diff --git a/Source/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from Source/configure/clients/TemplateServiceClientFactory.ts rename to src/configure/clients/TemplateServiceClientFactory.ts diff --git a/Source/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts similarity index 100% rename from Source/configure/clients/azure/appServiceClient.ts rename to src/configure/clients/azure/appServiceClient.ts diff --git a/Source/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts similarity index 100% rename from Source/configure/clients/azure/armRestClient.ts rename to src/configure/clients/azure/armRestClient.ts diff --git a/Source/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from Source/configure/clients/azure/azureResourceClient.ts rename to src/configure/clients/azure/azureResourceClient.ts diff --git a/Source/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from Source/configure/clients/devOps/azureDevOpsClient.ts rename to src/configure/clients/devOps/azureDevOpsClient.ts diff --git a/Source/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from Source/configure/clients/devOps/serviceConnectionClient.ts rename to src/configure/clients/devOps/serviceConnectionClient.ts diff --git a/Source/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from Source/configure/clients/github/TemplateServiceClient.ts rename to src/configure/clients/github/TemplateServiceClient.ts diff --git a/Source/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts similarity index 100% rename from Source/configure/clients/github/githubClient.ts rename to src/configure/clients/github/githubClient.ts diff --git a/Source/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from Source/configure/clients/modaRepositoryAnalysisClient.ts rename to src/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to src/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/Source/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from Source/configure/clients/provisioningServiceClientFactory.ts rename to src/configure/clients/provisioningServiceClientFactory.ts diff --git a/Source/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from Source/configure/clients/repositoryAnalyisClient.ts rename to src/configure/clients/repositoryAnalyisClient.ts diff --git a/Source/configure/clients/restClient.ts b/src/configure/clients/restClient.ts similarity index 100% rename from Source/configure/clients/restClient.ts rename to src/configure/clients/restClient.ts diff --git a/Source/configure/configure.ts b/src/configure/configure.ts similarity index 100% rename from Source/configure/configure.ts rename to src/configure/configure.ts diff --git a/Source/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from Source/configure/configurers/AksAzureResourceSelector.ts rename to src/configure/configurers/AksAzureResourceSelector.ts diff --git a/Source/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from Source/configure/configurers/IAzureResourceSelector.ts rename to src/configure/configurers/IAzureResourceSelector.ts diff --git a/Source/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from Source/configure/configurers/IProvisioningConfigurer.ts rename to src/configure/configurers/IProvisioningConfigurer.ts diff --git a/Source/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from Source/configure/configurers/ResourceSelectorFactory.ts rename to src/configure/configurers/ResourceSelectorFactory.ts diff --git a/Source/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from Source/configure/configurers/WebAppAzureResourceSelector.ts rename to src/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/Source/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from Source/configure/configurers/azurePipelineConfigurer.ts rename to src/configure/configurers/azurePipelineConfigurer.ts diff --git a/Source/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts similarity index 100% rename from Source/configure/configurers/configurerBase.ts rename to src/configure/configurers/configurerBase.ts diff --git a/Source/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts similarity index 100% rename from Source/configure/configurers/configurerFactory.ts rename to src/configure/configurers/configurerFactory.ts diff --git a/Source/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from Source/configure/configurers/localGithubWorkflowConfigurer.ts rename to src/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/Source/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from Source/configure/configurers/provisioningConfigurer.ts rename to src/configure/configurers/provisioningConfigurer.ts diff --git a/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to src/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/Source/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts similarity index 100% rename from Source/configure/helper/AssetHandler.ts rename to src/configure/helper/AssetHandler.ts diff --git a/Source/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts similarity index 100% rename from Source/configure/helper/DataSourceHandler.ts rename to src/configure/helper/DataSourceHandler.ts diff --git a/Source/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from Source/configure/helper/LocalGitRepoHelper.ts rename to src/configure/helper/LocalGitRepoHelper.ts diff --git a/Source/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts similarity index 100% rename from Source/configure/helper/azureSessionHelper.ts rename to src/configure/helper/azureSessionHelper.ts diff --git a/Source/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts similarity index 100% rename from Source/configure/helper/commonHelper.ts rename to src/configure/helper/commonHelper.ts diff --git a/Source/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts similarity index 100% rename from Source/configure/helper/controlProvider.ts rename to src/configure/helper/controlProvider.ts diff --git a/Source/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from Source/configure/helper/devOps/azureDevOpsHelper.ts rename to src/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/Source/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from Source/configure/helper/devOps/serviceConnectionHelper.ts rename to src/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/Source/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts similarity index 100% rename from Source/configure/helper/gitHubHelper.ts rename to src/configure/helper/gitHubHelper.ts diff --git a/Source/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts similarity index 100% rename from Source/configure/helper/graphHelper.ts rename to src/configure/helper/graphHelper.ts diff --git a/Source/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts similarity index 100% rename from Source/configure/helper/mustacheHelper.ts rename to src/configure/helper/mustacheHelper.ts diff --git a/Source/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from Source/configure/helper/remoteServiceUrlHelper.ts rename to src/configure/helper/remoteServiceUrlHelper.ts diff --git a/Source/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from Source/configure/helper/repoAnalysisHelper.ts rename to src/configure/helper/repoAnalysisHelper.ts diff --git a/Source/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from Source/configure/helper/sodium/SodiumLibHelper.ts rename to src/configure/helper/sodium/SodiumLibHelper.ts diff --git a/Source/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts similarity index 100% rename from Source/configure/helper/sodium/sodium.d.ts rename to src/configure/helper/sodium/sodium.d.ts diff --git a/Source/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts similarity index 100% rename from Source/configure/helper/telemetryHelper.ts rename to src/configure/helper/telemetryHelper.ts diff --git a/Source/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts similarity index 100% rename from Source/configure/helper/templateHelper.ts rename to src/configure/helper/templateHelper.ts diff --git a/Source/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts similarity index 100% rename from Source/configure/helper/templateParameterHelper.ts rename to src/configure/helper/templateParameterHelper.ts diff --git a/Source/configure/model/Contracts.ts b/src/configure/model/Contracts.ts similarity index 100% rename from Source/configure/model/Contracts.ts rename to src/configure/model/Contracts.ts diff --git a/Source/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts similarity index 100% rename from Source/configure/model/azureDevOps.ts rename to src/configure/model/azureDevOps.ts diff --git a/Source/configure/model/models.ts b/src/configure/model/models.ts similarity index 100% rename from Source/configure/model/models.ts rename to src/configure/model/models.ts diff --git a/Source/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts similarity index 100% rename from Source/configure/model/provisioningConfiguration.ts rename to src/configure/model/provisioningConfiguration.ts diff --git a/Source/configure/model/templateModels.ts b/src/configure/model/templateModels.ts similarity index 100% rename from Source/configure/model/templateModels.ts rename to src/configure/model/templateModels.ts diff --git a/Source/configure/resources/constants.ts b/src/configure/resources/constants.ts similarity index 100% rename from Source/configure/resources/constants.ts rename to src/configure/resources/constants.ts diff --git a/Source/configure/resources/messages.ts b/src/configure/resources/messages.ts similarity index 100% rename from Source/configure/resources/messages.ts rename to src/configure/resources/messages.ts diff --git a/Source/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts similarity index 100% rename from Source/configure/resources/telemetryKeys.ts rename to src/configure/resources/telemetryKeys.ts diff --git a/Source/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts similarity index 100% rename from Source/configure/resources/tracePoints.ts rename to src/configure/resources/tracePoints.ts diff --git a/Source/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts similarity index 100% rename from Source/configure/templateInputHelper/InputControl.ts rename to src/configure/templateInputHelper/InputControl.ts diff --git a/Source/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from Source/configure/templateInputHelper/InputControlProvider.ts rename to src/configure/templateInputHelper/InputControlProvider.ts diff --git a/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from Source/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to src/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from Source/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to src/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/Source/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from Source/configure/templateInputHelper/utilities/InputControlUtility.ts rename to src/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from Source/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to src/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to src/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejs.yml rename to src/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to src/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to src/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/Source/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml similarity index 100% rename from Source/configure/templates/dependencies/deployment.yml rename to src/configure/templates/dependencies/deployment.yml diff --git a/Source/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml similarity index 100% rename from Source/configure/templates/dependencies/ingress.yml rename to src/configure/templates/dependencies/ingress.yml diff --git a/Source/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from Source/configure/templates/dependencies/service-ingress.yml rename to src/configure/templates/dependencies/service-ingress.yml diff --git a/Source/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml similarity index 100% rename from Source/configure/templates/dependencies/service.yml rename to src/configure/templates/dependencies/service.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/Source/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts similarity index 100% rename from Source/configure/utilities/templateConverter.ts rename to src/configure/utilities/templateConverter.ts diff --git a/Source/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts similarity index 100% rename from Source/configure/utilities/utilities.ts rename to src/configure/utilities/utilities.ts diff --git a/Source/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from Source/configure/utilities/webAppNodeVersionConverter.ts rename to src/configure/utilities/webAppNodeVersionConverter.ts diff --git a/Source/extension.ts b/src/extension.ts similarity index 100% rename from Source/extension.ts rename to src/extension.ts diff --git a/Source/logger.ts b/src/logger.ts similarity index 100% rename from Source/logger.ts rename to src/logger.ts From 00068324c5b0c67ee403016e6d279caa93516270 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 27 Aug 2024 11:22:11 +0300 Subject: [PATCH 89/96] --- .github/dependabot.yml | 14 ++++++ .github/workflows/Dependabot.yml | 45 +++++++++++++++++ .github/workflows/GitHub.yml | 58 ++++++++++++++++++++++ .github/workflows/Node.yml | 85 ++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/Dependabot.yml create mode 100644 .github/workflows/GitHub.yml create mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..575fdde6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +enable-beta-ecosystems: true + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml new file mode 100644 index 00000000..387fece7 --- /dev/null +++ b/.github/workflows/Dependabot.yml @@ -0,0 +1,45 @@ +name: Dependabot + +concurrency: + group: Dependabot-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + +jobs: + Approve: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + Merge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml new file mode 100644 index 00000000..7b1e399c --- /dev/null +++ b/.github/workflows/GitHub.yml @@ -0,0 +1,58 @@ +name: GitHub + +concurrency: + group: GitHub-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + issues: write + pull-requests: write + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + Assign: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 + + steps: + - uses: pozil/auto-assign-issue@v2.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + assignees: NikolaRHristov + numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml new file mode 100644 index 00000000..dfdd1814 --- /dev/null +++ b/.github/workflows/Node.yml @@ -0,0 +1,85 @@ +name: Node + +concurrency: + group: Node-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + security-events: write + contents: write + pull-requests: write + +on: + workflow_dispatch: + push: + branches: [Current] + pull_request: + branches: [Current] + workflow_call: + +jobs: + Pre-Publish: + runs-on: ubuntu-latest + + env: + ADBLOCK: true + ASTRO_TELEMETRY_DISABLED: 1 + AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 + AZURE_CORE_COLLECT_TELEMETRY: 0 + CHOOSENIM_NO_ANALYTICS: 1 + DIEZ_DO_NOT_TRACK: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 + DO_NOT_TRACK: 1 + ET_NO_TELEMETRY: 1 + GATSBY_TELEMETRY_DISABLED: 1 + GATSBY_TELEMETRY_OPTOUT: 1 + GATSBY_TELEMETRY_OPT_OUT: 1 + GRIT_TELEMETRY_DISABLED: 1 + HASURA_GRAPHQL_ENABLE_TELEMETRY: false + HINT_TELEMETRY: off + HOMEBREW_NO_ANALYTICS: 1 + INFLUXD_REPORTING_DISABLED: true + ITERATIVE_DO_NOT_TRACK: 1 + NEXT_TELEMETRY_DEBUG: 1 + NEXT_TELEMETRY_DISABLED: 1 + NG_CLI_ANALYTICS: false + NUXT_TELEMETRY_DISABLED: 1 + PIN_DO_NOT_TRACK: 1 + POWERSHELL_TELEMETRY_OPTOUT: 1 + SAM_CLI_TELEMETRY: 0 + STNOUPGRADE: 1 + STRIPE_CLI_TELEMETRY_OPTOUT: 1 + TELEMETRY_DISABLED: 1 + TERRAFORM_TELEMETRY: 0 + + strategy: + matrix: + node-version: [18, 19, 20] + + steps: + - uses: actions/checkout@v4.1.7 + + - uses: pnpm/action-setup@v4.0.0 + with: + version: 9.3.0 + run_install: | + - recursive: true + args: [ + --link-workspace-packages=true, + --lockfile-only, + --prefer-frozen-lockfile=false, + --shamefully-hoist=false, + --shared-workspace-lockfile=true, + --strict-peer-dependencies=false, + --unsafe-perm=true + ] + + - uses: actions/setup-node@v4.0.3 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: ./pnpm-lock.yaml + + - run: pnpm install + working-directory: . From b23bc8bbca48fdbe9d33fe7d1282d1ad49c9486a Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 27 Aug 2024 13:01:50 +0300 Subject: [PATCH 90/96] --- Documentation/.nojekyll | 1 + Documentation/assets/custom.css | 54 + Documentation/assets/highlight.css | 22 + Documentation/assets/icons.js | 18 + Documentation/assets/icons.svg | 1 + Documentation/assets/main.js | 60 + Documentation/assets/navigation.js | 1 + Documentation/assets/search.js | 1 + Documentation/assets/style.css | 1448 ++++++++++++++++++++++ Documentation/index.html | 40 + Documentation/media/CONTRIBUTING.md | 18 + Documentation/media/ghpatpermissions.JPG | Bin 0 -> 321615 bytes Documentation/modules.html | 1 + 13 files changed, 1665 insertions(+) create mode 100644 Documentation/.nojekyll create mode 100644 Documentation/assets/custom.css create mode 100644 Documentation/assets/highlight.css create mode 100644 Documentation/assets/icons.js create mode 100644 Documentation/assets/icons.svg create mode 100644 Documentation/assets/main.js create mode 100644 Documentation/assets/navigation.js create mode 100644 Documentation/assets/search.js create mode 100644 Documentation/assets/style.css create mode 100644 Documentation/index.html create mode 100644 Documentation/media/CONTRIBUTING.md create mode 100644 Documentation/media/ghpatpermissions.JPG create mode 100644 Documentation/modules.html diff --git a/Documentation/.nojekyll b/Documentation/.nojekyll new file mode 100644 index 00000000..e2ac6616 --- /dev/null +++ b/Documentation/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/Documentation/assets/custom.css b/Documentation/assets/custom.css new file mode 100644 index 00000000..e360ec98 --- /dev/null +++ b/Documentation/assets/custom.css @@ -0,0 +1,54 @@ +:root { + --dark-color-background: #000; + --dark-color-background-secondary: #000; + --dark-code-background: #040404; + --color-accent: #2463eb; + --light-hl-0: #b58900; + --light-hl-1: #d33682; + --light-hl-2: #dc322f; + --light-hl-3: #2aa198; + --light-hl-4: #859900; + --dark-hl-0: #ffdd00; + --dark-hl-1: #ff66ff; + --dark-hl-2: #ff4444; + --dark-hl-3: #44ffff; + --dark-hl-4: #44ff44; +} + +body #tsd-search .field label { + left: 50%; + margin-left: -20px; + z-index: 1; + text-align: center; +} + +body #tsd-search.has-focus .field label { + display: none; +} + +body #tsd-search .field input { + z-index: 2; +} + +body pre, +body .tsd-page-toolbar, +body .tsd-generator { + border: none; +} + +body .tsd-navigation a, +body .tsd-navigation summary > span, +body .tsd-page-navigation a { + padding: 0.5rem; + border-radius: 8px; +} + +body .tsd-description .tsd-signatures .tsd-signature, +body .tsd-signature, +body .tsd-signatures .tsd-signature, +body .tsd-typography td, +body .tsd-typography th, +body code.tsd-tag { + border-radius: 12px; + border-width: 2px; +} diff --git a/Documentation/assets/highlight.css b/Documentation/assets/highlight.css new file mode 100644 index 00000000..5674cf39 --- /dev/null +++ b/Documentation/assets/highlight.css @@ -0,0 +1,22 @@ +:root { + --light-code-background: #FFFFFF; + --dark-code-background: #1E1E1E; +} + +@media (prefers-color-scheme: light) { :root { + --code-background: var(--light-code-background); +} } + +@media (prefers-color-scheme: dark) { :root { + --code-background: var(--dark-code-background); +} } + +:root[data-theme='light'] { + --code-background: var(--light-code-background); +} + +:root[data-theme='dark'] { + --code-background: var(--dark-code-background); +} + +pre, code { background: var(--code-background); } diff --git a/Documentation/assets/icons.js b/Documentation/assets/icons.js new file mode 100644 index 00000000..e88e8ca7 --- /dev/null +++ b/Documentation/assets/icons.js @@ -0,0 +1,18 @@ +(function() { + addIcons(); + function addIcons() { + if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons); + const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); + svg.innerHTML = `""`; + svg.style.display = "none"; + if (location.protocol === "file:") updateUseElements(); + } + + function updateUseElements() { + document.querySelectorAll("use").forEach(el => { + if (el.getAttribute("href").includes("#icon-")) { + el.setAttribute("href", el.getAttribute("href").replace(/.*#/, "#")); + } + }); + } +})() \ No newline at end of file diff --git a/Documentation/assets/icons.svg b/Documentation/assets/icons.svg new file mode 100644 index 00000000..e371b8b5 --- /dev/null +++ b/Documentation/assets/icons.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Documentation/assets/main.js b/Documentation/assets/main.js new file mode 100644 index 00000000..21a5d74d --- /dev/null +++ b/Documentation/assets/main.js @@ -0,0 +1,60 @@ +"use strict"; +window.translations={"copy":"Copy","copied":"Copied!","normally_hidden":"This member is normally hidden due to your filter settings."}; +"use strict";(()=>{var Pe=Object.create;var ie=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var Re=Object.getPrototypeOf,Me=Object.prototype.hasOwnProperty;var Fe=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var De=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of _e(e))!Me.call(t,i)&&i!==n&&ie(t,i,{get:()=>e[i],enumerable:!(r=Oe(e,i))||r.enumerable});return t};var Ae=(t,e,n)=>(n=t!=null?Pe(Re(t)):{},De(e||!t||!t.__esModule?ie(n,"default",{value:t,enumerable:!0}):n,t));var ue=Fe((ae,le)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,u],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ol?d+=2:a==l&&(n+=r[u+1]*i[d+1],u+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),m=s.str.charAt(1),p;m in s.node.edges?p=s.node.edges[m]:(p=new t.TokenSet,s.node.edges[m]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof ae=="object"?le.exports=n():e.lunr=n()}(this,function(){return t})})()});var se=[];function G(t,e){se.push({selector:e,constructor:t})}var U=class{constructor(){this.alwaysVisibleMember=null;this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){se.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!Ve(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function Ve(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var oe=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var pe=Ae(ue());async function ce(t,e){if(!window.searchData)return;let n=await fetch(window.searchData),r=new Blob([await n.arrayBuffer()]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();t.data=i,t.index=pe.Index.load(i.index),e.classList.remove("loading"),e.classList.add("ready")}function fe(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:t.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{ce(e,t)}),ce(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");i.addEventListener("mouseup",()=>{te(t)}),r.addEventListener("focus",()=>t.classList.add("has-focus")),He(t,i,r,e)}function He(t,e,n,r){n.addEventListener("input",oe(()=>{Ne(t,e,n,r)},200)),n.addEventListener("keydown",i=>{i.key=="Enter"?Be(e,t):i.key=="ArrowUp"?(de(e,n,-1),i.preventDefault()):i.key==="ArrowDown"&&(de(e,n,1),i.preventDefault())}),document.body.addEventListener("keypress",i=>{i.altKey||i.ctrlKey||i.metaKey||!n.matches(":focus")&&i.key==="/"&&(i.preventDefault(),n.focus())}),document.body.addEventListener("keyup",i=>{t.classList.contains("has-focus")&&(i.key==="Escape"||!e.matches(":focus-within")&&!n.matches(":focus"))&&(n.blur(),te(t))})}function te(t){t.classList.remove("has-focus")}function Ne(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;oa.score-o.score);for(let o=0,a=Math.min(10,s.length);o`,d=he(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=` + ${he(l.parent,i)}.${d}`);let m=document.createElement("li");m.classList.value=l.classes??"";let p=document.createElement("a");p.href=r.base+l.url,p.innerHTML=u+d,m.append(p),p.addEventListener("focus",()=>{e.querySelector(".current")?.classList.remove("current"),m.classList.add("current")}),e.appendChild(m)}}function de(t,e,n){let r=t.querySelector(".current");if(!r)r=t.querySelector(n==1?"li:first-child":"li:last-child"),r&&r.classList.add("current");else{let i=r;if(n===1)do i=i.nextElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);else do i=i.previousElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);i?(r.classList.remove("current"),i.classList.add("current")):n===-1&&(r.classList.remove("current"),e.focus())}}function Be(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),te(e)}}function he(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(ee(t.substring(s,o)),`${ee(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(ee(t.substring(s))),i.join("")}var je={"&":"&","<":"<",">":">","'":"'",'"':"""};function ee(t){return t.replace(/[&<>"'"]/g,e=>je[e])}var I=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",ye="mousemove",N="mouseup",J={x:0,y:0},me=!1,ne=!1,qe=!1,D=!1,ve=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(ve?"is-mobile":"not-mobile");ve&&"ontouchstart"in document.documentElement&&(qe=!0,F="touchstart",ye="touchmove",N="touchend");document.addEventListener(F,t=>{ne=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(ye,t=>{if(ne&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(N,()=>{ne=!1});document.addEventListener("click",t=>{me&&(t.preventDefault(),t.stopImmediatePropagation(),me=!1)});var X=class extends I{constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(N,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(F,n=>this.onDocumentPointerDown(n)),document.addEventListener(N,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var re;try{re=localStorage}catch{re={getItem(){return null},setItem(){}}}var Q=re;var ge=document.head.appendChild(document.createElement("style"));ge.dataset.for="filters";var Y=class extends I{constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ge.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } +`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=Q.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){Q.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),this.app.updateIndexVisibility()}};var Z=class extends I{constructor(e){super(e),this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let n=Q.getItem(this.key);this.el.open=n?n==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let r=this.summary.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function Ee(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,xe(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),xe(t.value)})}function xe(t){document.documentElement.dataset.theme=t}var K;function we(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",Le),Le())}async function Le(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();K=t.dataset.base,K.endsWith("/")||(K+="/"),t.innerHTML="";for(let s of i)Se(s,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function Se(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-accordion`:"tsd-accordion";let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.dataset.key=i.join("$"),o.innerHTML='',be(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)Se(u,l,i)}else be(t,r,t.class)}function be(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=K+t.path,n&&(r.className=n),location.pathname===r.pathname&&!r.href.includes("#")&&r.classList.add("current"),t.kind&&(r.innerHTML=``),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Te=document.getElementById("tsd-theme");Te&&Ee(Te);var $e=new U;Object.defineProperty(window,"app",{value:$e});fe();we();})(); +/*! Bundled license information: + +lunr/lunr.js: + (** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + *) + (*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + *) + (*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + *) +*/ diff --git a/Documentation/assets/navigation.js b/Documentation/assets/navigation.js new file mode 100644 index 00000000..e7335e96 --- /dev/null +++ b/Documentation/assets/navigation.js @@ -0,0 +1 @@ +window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACouOBQApu0wNAgAAAA==" \ No newline at end of file diff --git a/Documentation/assets/search.js b/Documentation/assets/search.js new file mode 100644 index 00000000..31a4e1af --- /dev/null +++ b/Documentation/assets/search.js @@ -0,0 +1 @@ +window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACj2MQQqDMBRE7zLr4MKuzA16ATfioiQjfDD/S0xtQby7pEp384bH25Hts8IPo4No5Bd+x8a8iik82ubRdHCYhHOsGvSVCIdgKVELHKKF92+Ot9YzFMv/5sZcGJ9Xu16LLJxFWek4TiJTfzuBAAAA"; \ No newline at end of file diff --git a/Documentation/assets/style.css b/Documentation/assets/style.css new file mode 100644 index 00000000..9d619a64 --- /dev/null +++ b/Documentation/assets/style.css @@ -0,0 +1,1448 @@ +:root { + /* Light */ + --light-color-background: #f2f4f8; + --light-color-background-secondary: #eff0f1; + --light-color-warning-text: #222; + --light-color-background-warning: #e6e600; + --light-color-icon-background: var(--light-color-background); + --light-color-accent: #c5c7c9; + --light-color-active-menu-item: var(--light-color-accent); + --light-color-text: #222; + --light-color-text-aside: #6e6e6e; + --light-color-link: #1f70c2; + --light-color-focus-outline: #3584e4; + + --light-color-ts-keyword: #056bd6; + --light-color-ts-project: #b111c9; + --light-color-ts-module: var(--light-color-ts-project); + --light-color-ts-namespace: var(--light-color-ts-project); + --light-color-ts-enum: #7e6f15; + --light-color-ts-enum-member: var(--light-color-ts-enum); + --light-color-ts-variable: #4760ec; + --light-color-ts-function: #572be7; + --light-color-ts-class: #1f70c2; + --light-color-ts-interface: #108024; + --light-color-ts-constructor: var(--light-color-ts-class); + --light-color-ts-property: var(--light-color-ts-variable); + --light-color-ts-method: var(--light-color-ts-function); + --light-color-ts-call-signature: var(--light-color-ts-method); + --light-color-ts-index-signature: var(--light-color-ts-property); + --light-color-ts-constructor-signature: var(--light-color-ts-constructor); + --light-color-ts-parameter: var(--light-color-ts-variable); + /* type literal not included as links will never be generated to it */ + --light-color-ts-type-parameter: #a55c0e; + --light-color-ts-accessor: var(--light-color-ts-property); + --light-color-ts-get-signature: var(--light-color-ts-accessor); + --light-color-ts-set-signature: var(--light-color-ts-accessor); + --light-color-ts-type-alias: #d51270; + /* reference not included as links will be colored with the kind that it points to */ + --light-color-document: #000000; + + --light-external-icon: url("data:image/svg+xml;utf8,"); + --light-color-scheme: light; + + /* Dark */ + --dark-color-background: #2b2e33; + --dark-color-background-secondary: #1e2024; + --dark-color-background-warning: #bebe00; + --dark-color-warning-text: #222; + --dark-color-icon-background: var(--dark-color-background-secondary); + --dark-color-accent: #9096a2; + --dark-color-active-menu-item: #5d5d6a; + --dark-color-text: #f5f5f5; + --dark-color-text-aside: #dddddd; + --dark-color-link: #00aff4; + --dark-color-focus-outline: #4c97f2; + + --dark-color-ts-keyword: #3399ff; + --dark-color-ts-project: #e358ff; + --dark-color-ts-module: var(--dark-color-ts-project); + --dark-color-ts-namespace: var(--dark-color-ts-project); + --dark-color-ts-enum: #f4d93e; + --dark-color-ts-enum-member: var(--dark-color-ts-enum); + --dark-color-ts-variable: #798dff; + --dark-color-ts-function: #a280ff; + --dark-color-ts-class: #8ac4ff; + --dark-color-ts-interface: #6cff87; + --dark-color-ts-constructor: var(--dark-color-ts-class); + --dark-color-ts-property: var(--dark-color-ts-variable); + --dark-color-ts-method: var(--dark-color-ts-function); + --dark-color-ts-call-signature: var(--dark-color-ts-method); + --dark-color-ts-index-signature: var(--dark-color-ts-property); + --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); + --dark-color-ts-parameter: var(--dark-color-ts-variable); + /* type literal not included as links will never be generated to it */ + --dark-color-ts-type-parameter: #e07d13; + --dark-color-ts-accessor: var(--dark-color-ts-property); + --dark-color-ts-get-signature: var(--dark-color-ts-accessor); + --dark-color-ts-set-signature: var(--dark-color-ts-accessor); + --dark-color-ts-type-alias: #ff6492; + /* reference not included as links will be colored with the kind that it points to */ + --dark-color-document: #ffffff; + + --dark-external-icon: url("data:image/svg+xml;utf8,"); + --dark-color-scheme: dark; +} + +@media (prefers-color-scheme: light) { + :root { + --color-background: var(--light-color-background); + --color-background-secondary: var(--light-color-background-secondary); + --color-background-warning: var(--light-color-background-warning); + --color-warning-text: var(--light-color-warning-text); + --color-icon-background: var(--light-color-icon-background); + --color-accent: var(--light-color-accent); + --color-active-menu-item: var(--light-color-active-menu-item); + --color-text: var(--light-color-text); + --color-text-aside: var(--light-color-text-aside); + --color-link: var(--light-color-link); + --color-focus-outline: var(--light-color-focus-outline); + + --color-ts-keyword: var(--light-color-ts-keyword); + --color-ts-module: var(--light-color-ts-module); + --color-ts-namespace: var(--light-color-ts-namespace); + --color-ts-enum: var(--light-color-ts-enum); + --color-ts-enum-member: var(--light-color-ts-enum-member); + --color-ts-variable: var(--light-color-ts-variable); + --color-ts-function: var(--light-color-ts-function); + --color-ts-class: var(--light-color-ts-class); + --color-ts-interface: var(--light-color-ts-interface); + --color-ts-constructor: var(--light-color-ts-constructor); + --color-ts-property: var(--light-color-ts-property); + --color-ts-method: var(--light-color-ts-method); + --color-ts-call-signature: var(--light-color-ts-call-signature); + --color-ts-index-signature: var(--light-color-ts-index-signature); + --color-ts-constructor-signature: var( + --light-color-ts-constructor-signature + ); + --color-ts-parameter: var(--light-color-ts-parameter); + --color-ts-type-parameter: var(--light-color-ts-type-parameter); + --color-ts-accessor: var(--light-color-ts-accessor); + --color-ts-get-signature: var(--light-color-ts-get-signature); + --color-ts-set-signature: var(--light-color-ts-set-signature); + --color-ts-type-alias: var(--light-color-ts-type-alias); + --color-document: var(--light-color-document); + + --external-icon: var(--light-external-icon); + --color-scheme: var(--light-color-scheme); + } +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--dark-color-background); + --color-background-secondary: var(--dark-color-background-secondary); + --color-background-warning: var(--dark-color-background-warning); + --color-warning-text: var(--dark-color-warning-text); + --color-icon-background: var(--dark-color-icon-background); + --color-accent: var(--dark-color-accent); + --color-active-menu-item: var(--dark-color-active-menu-item); + --color-text: var(--dark-color-text); + --color-text-aside: var(--dark-color-text-aside); + --color-link: var(--dark-color-link); + --color-focus-outline: var(--dark-color-focus-outline); + + --color-ts-keyword: var(--dark-color-ts-keyword); + --color-ts-module: var(--dark-color-ts-module); + --color-ts-namespace: var(--dark-color-ts-namespace); + --color-ts-enum: var(--dark-color-ts-enum); + --color-ts-enum-member: var(--dark-color-ts-enum-member); + --color-ts-variable: var(--dark-color-ts-variable); + --color-ts-function: var(--dark-color-ts-function); + --color-ts-class: var(--dark-color-ts-class); + --color-ts-interface: var(--dark-color-ts-interface); + --color-ts-constructor: var(--dark-color-ts-constructor); + --color-ts-property: var(--dark-color-ts-property); + --color-ts-method: var(--dark-color-ts-method); + --color-ts-call-signature: var(--dark-color-ts-call-signature); + --color-ts-index-signature: var(--dark-color-ts-index-signature); + --color-ts-constructor-signature: var( + --dark-color-ts-constructor-signature + ); + --color-ts-parameter: var(--dark-color-ts-parameter); + --color-ts-type-parameter: var(--dark-color-ts-type-parameter); + --color-ts-accessor: var(--dark-color-ts-accessor); + --color-ts-get-signature: var(--dark-color-ts-get-signature); + --color-ts-set-signature: var(--dark-color-ts-set-signature); + --color-ts-type-alias: var(--dark-color-ts-type-alias); + --color-document: var(--dark-color-document); + + --external-icon: var(--dark-external-icon); + --color-scheme: var(--dark-color-scheme); + } +} + +html { + color-scheme: var(--color-scheme); +} + +body { + margin: 0; +} + +:root[data-theme="light"] { + --color-background: var(--light-color-background); + --color-background-secondary: var(--light-color-background-secondary); + --color-background-warning: var(--light-color-background-warning); + --color-warning-text: var(--light-color-warning-text); + --color-icon-background: var(--light-color-icon-background); + --color-accent: var(--light-color-accent); + --color-active-menu-item: var(--light-color-active-menu-item); + --color-text: var(--light-color-text); + --color-text-aside: var(--light-color-text-aside); + --color-link: var(--light-color-link); + --color-focus-outline: var(--light-color-focus-outline); + + --color-ts-keyword: var(--light-color-ts-keyword); + --color-ts-module: var(--light-color-ts-module); + --color-ts-namespace: var(--light-color-ts-namespace); + --color-ts-enum: var(--light-color-ts-enum); + --color-ts-enum-member: var(--light-color-ts-enum-member); + --color-ts-variable: var(--light-color-ts-variable); + --color-ts-function: var(--light-color-ts-function); + --color-ts-class: var(--light-color-ts-class); + --color-ts-interface: var(--light-color-ts-interface); + --color-ts-constructor: var(--light-color-ts-constructor); + --color-ts-property: var(--light-color-ts-property); + --color-ts-method: var(--light-color-ts-method); + --color-ts-call-signature: var(--light-color-ts-call-signature); + --color-ts-index-signature: var(--light-color-ts-index-signature); + --color-ts-constructor-signature: var( + --light-color-ts-constructor-signature + ); + --color-ts-parameter: var(--light-color-ts-parameter); + --color-ts-type-parameter: var(--light-color-ts-type-parameter); + --color-ts-accessor: var(--light-color-ts-accessor); + --color-ts-get-signature: var(--light-color-ts-get-signature); + --color-ts-set-signature: var(--light-color-ts-set-signature); + --color-ts-type-alias: var(--light-color-ts-type-alias); + --color-document: var(--light-color-document); + + --external-icon: var(--light-external-icon); + --color-scheme: var(--light-color-scheme); +} + +:root[data-theme="dark"] { + --color-background: var(--dark-color-background); + --color-background-secondary: var(--dark-color-background-secondary); + --color-background-warning: var(--dark-color-background-warning); + --color-warning-text: var(--dark-color-warning-text); + --color-icon-background: var(--dark-color-icon-background); + --color-accent: var(--dark-color-accent); + --color-active-menu-item: var(--dark-color-active-menu-item); + --color-text: var(--dark-color-text); + --color-text-aside: var(--dark-color-text-aside); + --color-link: var(--dark-color-link); + --color-focus-outline: var(--dark-color-focus-outline); + + --color-ts-keyword: var(--dark-color-ts-keyword); + --color-ts-module: var(--dark-color-ts-module); + --color-ts-namespace: var(--dark-color-ts-namespace); + --color-ts-enum: var(--dark-color-ts-enum); + --color-ts-enum-member: var(--dark-color-ts-enum-member); + --color-ts-variable: var(--dark-color-ts-variable); + --color-ts-function: var(--dark-color-ts-function); + --color-ts-class: var(--dark-color-ts-class); + --color-ts-interface: var(--dark-color-ts-interface); + --color-ts-constructor: var(--dark-color-ts-constructor); + --color-ts-property: var(--dark-color-ts-property); + --color-ts-method: var(--dark-color-ts-method); + --color-ts-call-signature: var(--dark-color-ts-call-signature); + --color-ts-index-signature: var(--dark-color-ts-index-signature); + --color-ts-constructor-signature: var( + --dark-color-ts-constructor-signature + ); + --color-ts-parameter: var(--dark-color-ts-parameter); + --color-ts-type-parameter: var(--dark-color-ts-type-parameter); + --color-ts-accessor: var(--dark-color-ts-accessor); + --color-ts-get-signature: var(--dark-color-ts-get-signature); + --color-ts-set-signature: var(--dark-color-ts-set-signature); + --color-ts-type-alias: var(--dark-color-ts-type-alias); + --color-document: var(--dark-color-document); + + --external-icon: var(--dark-external-icon); + --color-scheme: var(--dark-color-scheme); +} + +*:focus-visible, +.tsd-accordion-summary:focus-visible svg { + outline: 2px solid var(--color-focus-outline); +} + +.always-visible, +.always-visible .tsd-signatures { + display: inherit !important; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + line-height: 1.2; +} + +h1 { + font-size: 1.875rem; + margin: 0.67rem 0; +} + +h2 { + font-size: 1.5rem; + margin: 0.83rem 0; +} + +h3 { + font-size: 1.25rem; + margin: 1rem 0; +} + +h4 { + font-size: 1.05rem; + margin: 1.33rem 0; +} + +h5 { + font-size: 1rem; + margin: 1.5rem 0; +} + +h6 { + font-size: 0.875rem; + margin: 2.33rem 0; +} + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +.container { + max-width: 1700px; + padding: 0 2rem; +} + +/* Footer */ +footer { + border-top: 1px solid var(--color-accent); + padding-top: 1rem; + padding-bottom: 1rem; + max-height: 3.5rem; +} +footer > p { + margin: 0 1em; +} + +.container-main { + margin: 0 auto; + /* toolbar, footer, margin */ + min-height: calc(100vh - 41px - 56px - 4rem); +} + +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes fade-out { + from { + opacity: 1; + visibility: visible; + } + to { + opacity: 0; + } +} +@keyframes fade-in-delayed { + 0% { + opacity: 0; + } + 33% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@keyframes fade-out-delayed { + 0% { + opacity: 1; + visibility: visible; + } + 66% { + opacity: 0; + } + 100% { + opacity: 0; + } +} +@keyframes pop-in-from-right { + from { + transform: translate(100%, 0); + } + to { + transform: translate(0, 0); + } +} +@keyframes pop-out-to-right { + from { + transform: translate(0, 0); + visibility: visible; + } + to { + transform: translate(100%, 0); + } +} +body { + background: var(--color-background); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + font-size: 16px; + color: var(--color-text); +} + +a { + color: var(--color-link); + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +a.external[target="_blank"] { + background-image: var(--external-icon); + background-position: top 3px right; + background-repeat: no-repeat; + padding-right: 13px; +} +a.tsd-anchor-link { + color: var(--color-text); +} + +code, +pre { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + padding: 0.2em; + margin: 0; + font-size: 0.875rem; + border-radius: 0.8em; +} + +pre { + position: relative; + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; + padding: 10px; + border: 1px solid var(--color-accent); +} +pre code { + padding: 0; + font-size: 100%; +} +pre > button { + position: absolute; + top: 10px; + right: 10px; + opacity: 0; + transition: opacity 0.1s; + box-sizing: border-box; +} +pre:hover > button, +pre > button.visible { + opacity: 1; +} + +blockquote { + margin: 1em 0; + padding-left: 1em; + border-left: 4px solid gray; +} + +.tsd-typography { + line-height: 1.333em; +} +.tsd-typography ul { + list-style: square; + padding: 0 0 0 20px; + margin: 0; +} +.tsd-typography .tsd-index-panel h3, +.tsd-index-panel .tsd-typography h3, +.tsd-typography h4, +.tsd-typography h5, +.tsd-typography h6 { + font-size: 1em; +} +.tsd-typography h5, +.tsd-typography h6 { + font-weight: normal; +} +.tsd-typography p, +.tsd-typography ul, +.tsd-typography ol { + margin: 1em 0; +} +.tsd-typography table { + border-collapse: collapse; + border: none; +} +.tsd-typography td, +.tsd-typography th { + padding: 6px 13px; + border: 1px solid var(--color-accent); +} +.tsd-typography thead, +.tsd-typography tr:nth-child(even) { + background-color: var(--color-background-secondary); +} + +.tsd-breadcrumb { + margin: 0; + padding: 0; + color: var(--color-text-aside); +} +.tsd-breadcrumb a { + color: var(--color-text-aside); + text-decoration: none; +} +.tsd-breadcrumb a:hover { + text-decoration: underline; +} +.tsd-breadcrumb li { + display: inline; +} +.tsd-breadcrumb li:after { + content: " / "; +} + +.tsd-comment-tags { + display: flex; + flex-direction: column; +} +dl.tsd-comment-tag-group { + display: flex; + align-items: center; + overflow: hidden; + margin: 0.5em 0; +} +dl.tsd-comment-tag-group dt { + display: flex; + margin-right: 0.5em; + font-size: 0.875em; + font-weight: normal; +} +dl.tsd-comment-tag-group dd { + margin: 0; +} +code.tsd-tag { + padding: 0.25em 0.4em; + border: 0.1em solid var(--color-accent); + margin-right: 0.25em; + font-size: 70%; +} +h1 code.tsd-tag:first-of-type { + margin-left: 0.25em; +} + +dl.tsd-comment-tag-group dd:before, +dl.tsd-comment-tag-group dd:after { + content: " "; +} +dl.tsd-comment-tag-group dd pre, +dl.tsd-comment-tag-group dd:after { + clear: both; +} +dl.tsd-comment-tag-group p { + margin: 0; +} + +.tsd-panel.tsd-comment .lead { + font-size: 1.1em; + line-height: 1.333em; + margin-bottom: 2em; +} +.tsd-panel.tsd-comment .lead:last-child { + margin-bottom: 0; +} + +.tsd-filter-visibility h4 { + font-size: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.5rem; + margin: 0; +} +.tsd-filter-item:not(:last-child) { + margin-bottom: 0.5rem; +} +.tsd-filter-input { + display: flex; + width: -moz-fit-content; + width: fit-content; + align-items: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; +} +.tsd-filter-input input[type="checkbox"] { + cursor: pointer; + position: absolute; + width: 1.5em; + height: 1.5em; + opacity: 0; +} +.tsd-filter-input input[type="checkbox"]:disabled { + pointer-events: none; +} +.tsd-filter-input svg { + cursor: pointer; + width: 1.5em; + height: 1.5em; + margin-right: 0.5em; + border-radius: 0.33em; + /* Leaving this at full opacity breaks event listeners on Firefox. + Don't remove unless you know what you're doing. */ + opacity: 0.99; +} +.tsd-filter-input input[type="checkbox"]:focus-visible + svg { + outline: 2px solid var(--color-focus-outline); +} +.tsd-checkbox-background { + fill: var(--color-accent); +} +input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { + stroke: var(--color-text); +} +.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { + fill: var(--color-background); + stroke: var(--color-accent); + stroke-width: 0.25rem; +} +.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { + stroke: var(--color-accent); +} + +.settings-label { + font-weight: bold; + text-transform: uppercase; + display: inline-block; +} + +.tsd-filter-visibility .settings-label { + margin: 0.75rem 0 0.5rem 0; +} + +.tsd-theme-toggle .settings-label { + margin: 0.75rem 0.75rem 0 0; +} + +.tsd-hierarchy { + list-style: square; + margin: 0; +} +.tsd-hierarchy .target { + font-weight: bold; +} + +.tsd-full-hierarchy:not(:last-child) { + margin-bottom: 1em; + padding-bottom: 1em; + border-bottom: 1px solid var(--color-accent); +} +.tsd-full-hierarchy, +.tsd-full-hierarchy ul { + list-style: none; + margin: 0; + padding: 0; +} +.tsd-full-hierarchy ul { + padding-left: 1.5rem; +} +.tsd-full-hierarchy a { + padding: 0.25rem 0 !important; + font-size: 1rem; + display: inline-flex; + align-items: center; + color: var(--color-text); +} + +.tsd-panel-group.tsd-index-group { + margin-bottom: 0; +} +.tsd-index-panel .tsd-index-list { + list-style: none; + line-height: 1.333em; + margin: 0; + padding: 0.25rem 0 0 0; + overflow: hidden; + display: grid; + grid-template-columns: repeat(3, 1fr); + column-gap: 1rem; + grid-template-rows: auto; +} +@media (max-width: 1024px) { + .tsd-index-panel .tsd-index-list { + grid-template-columns: repeat(2, 1fr); + } +} +@media (max-width: 768px) { + .tsd-index-panel .tsd-index-list { + grid-template-columns: repeat(1, 1fr); + } +} +.tsd-index-panel .tsd-index-list li { + -webkit-page-break-inside: avoid; + -moz-page-break-inside: avoid; + -ms-page-break-inside: avoid; + -o-page-break-inside: avoid; + page-break-inside: avoid; +} + +.tsd-flag { + display: inline-block; + padding: 0.25em 0.4em; + border-radius: 4px; + color: var(--color-comment-tag-text); + background-color: var(--color-comment-tag); + text-indent: 0; + font-size: 75%; + line-height: 1; + font-weight: normal; +} + +.tsd-anchor { + position: relative; + top: -100px; +} + +.tsd-member { + position: relative; +} +.tsd-member .tsd-anchor + h3 { + display: flex; + align-items: center; + margin-top: 0; + margin-bottom: 0; + border-bottom: none; +} + +.tsd-navigation.settings { + margin: 1rem 0; +} +.tsd-navigation > a, +.tsd-navigation .tsd-accordion-summary { + width: calc(100% - 0.25rem); + display: flex; + align-items: center; +} +.tsd-navigation a, +.tsd-navigation summary > span, +.tsd-page-navigation a { + display: flex; + width: calc(100% - 0.25rem); + align-items: center; + padding: 0.25rem; + color: var(--color-text); + text-decoration: none; + box-sizing: border-box; +} +.tsd-navigation a.current, +.tsd-page-navigation a.current { + background: var(--color-active-menu-item); +} +.tsd-navigation a:hover, +.tsd-page-navigation a:hover { + text-decoration: underline; +} +.tsd-navigation ul, +.tsd-page-navigation ul { + margin-top: 0; + margin-bottom: 0; + padding: 0; + list-style: none; +} +.tsd-navigation li, +.tsd-page-navigation li { + padding: 0; + max-width: 100%; +} +.tsd-navigation .tsd-nav-link { + display: none; +} +.tsd-nested-navigation { + margin-left: 3rem; +} +.tsd-nested-navigation > li > details { + margin-left: -1.5rem; +} +.tsd-small-nested-navigation { + margin-left: 1.5rem; +} +.tsd-small-nested-navigation > li > details { + margin-left: -1.5rem; +} + +.tsd-page-navigation-section { + margin-left: 10px; +} +.tsd-page-navigation-section > summary { + padding: 0.25rem; +} +.tsd-page-navigation-section > div { + margin-left: 20px; +} +.tsd-page-navigation ul { + padding-left: 1.75rem; +} + +#tsd-sidebar-links a { + margin-top: 0; + margin-bottom: 0.5rem; + line-height: 1.25rem; +} +#tsd-sidebar-links a:last-of-type { + margin-bottom: 0; +} + +a.tsd-index-link { + padding: 0.25rem 0 !important; + font-size: 1rem; + line-height: 1.25rem; + display: inline-flex; + align-items: center; + color: var(--color-text); +} +.tsd-accordion-summary { + list-style-type: none; /* hide marker on non-safari */ + outline: none; /* broken on safari, so just hide it */ +} +.tsd-accordion-summary::-webkit-details-marker { + display: none; /* hide marker on safari */ +} +.tsd-accordion-summary, +.tsd-accordion-summary a { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + + cursor: pointer; +} +.tsd-accordion-summary a { + width: calc(100% - 1.5rem); +} +.tsd-accordion-summary > * { + margin-top: 0; + margin-bottom: 0; + padding-top: 0; + padding-bottom: 0; +} +.tsd-accordion .tsd-accordion-summary > svg { + margin-left: 0.25rem; + vertical-align: text-top; +} +.tsd-index-content > :not(:first-child) { + margin-top: 0.75rem; +} +.tsd-index-heading { + margin-top: 1.5rem; + margin-bottom: 0.75rem; +} + +.tsd-kind-icon { + margin-right: 0.5rem; + width: 1.25rem; + height: 1.25rem; + min-width: 1.25rem; + min-height: 1.25rem; +} +.tsd-kind-icon path { + transform-origin: center; + transform: scale(1.1); +} +.tsd-signature > .tsd-kind-icon { + margin-right: 0.8rem; +} + +.tsd-panel { + margin-bottom: 2.5rem; +} +.tsd-panel.tsd-member { + margin-bottom: 4rem; +} +.tsd-panel:empty { + display: none; +} +.tsd-panel > h1, +.tsd-panel > h2, +.tsd-panel > h3 { + margin: 1.5rem -1.5rem 0.75rem -1.5rem; + padding: 0 1.5rem 0.75rem 1.5rem; +} +.tsd-panel > h1.tsd-before-signature, +.tsd-panel > h2.tsd-before-signature, +.tsd-panel > h3.tsd-before-signature { + margin-bottom: 0; + border-bottom: none; +} + +.tsd-panel-group { + margin: 2rem 0; +} +.tsd-panel-group.tsd-index-group { + margin: 2rem 0; +} +.tsd-panel-group.tsd-index-group details { + margin: 2rem 0; +} +.tsd-panel-group > .tsd-accordion-summary { + margin-bottom: 1rem; +} + +#tsd-search { + transition: background-color 0.2s; +} +#tsd-search .title { + position: relative; + z-index: 2; +} +#tsd-search .field { + position: absolute; + left: 0; + top: 0; + right: 2.5rem; + height: 100%; +} +#tsd-search .field input { + box-sizing: border-box; + position: relative; + top: -50px; + z-index: 1; + width: 100%; + padding: 0 10px; + opacity: 0; + outline: 0; + border: 0; + background: transparent; + color: var(--color-text); +} +#tsd-search .field label { + position: absolute; + overflow: hidden; + right: -40px; +} +#tsd-search .field input, +#tsd-search .title, +#tsd-toolbar-links a { + transition: opacity 0.2s; +} +#tsd-search .results { + position: absolute; + visibility: hidden; + top: 40px; + width: 100%; + margin: 0; + padding: 0; + list-style: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); +} +#tsd-search .results li { + background-color: var(--color-background); + line-height: initial; + padding: 4px; +} +#tsd-search .results li:nth-child(even) { + background-color: var(--color-background-secondary); +} +#tsd-search .results li.state { + display: none; +} +#tsd-search .results li.current:not(.no-results), +#tsd-search .results li:hover:not(.no-results) { + background-color: var(--color-accent); +} +#tsd-search .results a { + display: flex; + align-items: center; + padding: 0.25rem; + box-sizing: border-box; +} +#tsd-search .results a:before { + top: 10px; +} +#tsd-search .results span.parent { + color: var(--color-text-aside); + font-weight: normal; +} +#tsd-search.has-focus { + background-color: var(--color-accent); +} +#tsd-search.has-focus .field input { + top: 0; + opacity: 1; +} +#tsd-search.has-focus .title, +#tsd-search.has-focus #tsd-toolbar-links a { + z-index: 0; + opacity: 0; +} +#tsd-search.has-focus .results { + visibility: visible; +} +#tsd-search.loading .results li.state.loading { + display: block; +} +#tsd-search.failure .results li.state.failure { + display: block; +} + +#tsd-toolbar-links { + position: absolute; + top: 0; + right: 2rem; + height: 100%; + display: flex; + align-items: center; + justify-content: flex-end; +} +#tsd-toolbar-links a { + margin-left: 1.5rem; +} +#tsd-toolbar-links a:hover { + text-decoration: underline; +} + +.tsd-signature { + margin: 0 0 1rem 0; + padding: 1rem 0.5rem; + border: 1px solid var(--color-accent); + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 14px; + overflow-x: auto; +} + +.tsd-signature-keyword { + color: var(--color-ts-keyword); + font-weight: normal; +} + +.tsd-signature-symbol { + color: var(--color-text-aside); + font-weight: normal; +} + +.tsd-signature-type { + font-style: italic; + font-weight: normal; +} + +.tsd-signatures { + padding: 0; + margin: 0 0 1em 0; + list-style-type: none; +} +.tsd-signatures .tsd-signature { + margin: 0; + border-color: var(--color-accent); + border-width: 1px 0; + transition: background-color 0.1s; +} +.tsd-signatures .tsd-index-signature:not(:last-child) { + margin-bottom: 1em; +} +.tsd-signatures .tsd-index-signature .tsd-signature { + border-width: 1px; +} +.tsd-description .tsd-signatures .tsd-signature { + border-width: 1px; +} + +ul.tsd-parameter-list, +ul.tsd-type-parameter-list { + list-style: square; + margin: 0; + padding-left: 20px; +} +ul.tsd-parameter-list > li.tsd-parameter-signature, +ul.tsd-type-parameter-list > li.tsd-parameter-signature { + list-style: none; + margin-left: -20px; +} +ul.tsd-parameter-list h5, +ul.tsd-type-parameter-list h5 { + font-size: 16px; + margin: 1em 0 0.5em 0; +} +.tsd-sources { + margin-top: 1rem; + font-size: 0.875em; +} +.tsd-sources a { + color: var(--color-text-aside); + text-decoration: underline; +} +.tsd-sources ul { + list-style: none; + padding: 0; +} + +.tsd-page-toolbar { + position: sticky; + z-index: 1; + top: 0; + left: 0; + width: 100%; + color: var(--color-text); + background: var(--color-background-secondary); + border-bottom: 1px var(--color-accent) solid; + transition: transform 0.3s ease-in-out; +} +.tsd-page-toolbar a { + color: var(--color-text); + text-decoration: none; +} +.tsd-page-toolbar a.title { + font-weight: bold; +} +.tsd-page-toolbar a.title:hover { + text-decoration: underline; +} +.tsd-page-toolbar .tsd-toolbar-contents { + display: flex; + justify-content: space-between; + height: 2.5rem; + margin: 0 auto; +} +.tsd-page-toolbar .table-cell { + position: relative; + white-space: nowrap; + line-height: 40px; +} +.tsd-page-toolbar .table-cell:first-child { + width: 100%; +} +.tsd-page-toolbar .tsd-toolbar-icon { + box-sizing: border-box; + line-height: 0; + padding: 12px 0; +} + +.tsd-widget { + display: inline-block; + overflow: hidden; + opacity: 0.8; + height: 40px; + transition: + opacity 0.1s, + background-color 0.2s; + vertical-align: bottom; + cursor: pointer; +} +.tsd-widget:hover { + opacity: 0.9; +} +.tsd-widget.active { + opacity: 1; + background-color: var(--color-accent); +} +.tsd-widget.no-caption { + width: 40px; +} +.tsd-widget.no-caption:before { + margin: 0; +} + +.tsd-widget.options, +.tsd-widget.menu { + display: none; +} +input[type="checkbox"] + .tsd-widget:before { + background-position: -120px 0; +} +input[type="checkbox"]:checked + .tsd-widget:before { + background-position: -160px 0; +} + +img { + max-width: 100%; +} + +.tsd-anchor-icon { + display: inline-flex; + align-items: center; + margin-left: 0.5rem; + vertical-align: middle; + color: var(--color-text); +} + +.tsd-anchor-icon svg { + width: 1em; + height: 1em; + visibility: hidden; +} + +.tsd-anchor-link:hover > .tsd-anchor-icon svg { + visibility: visible; +} + +.deprecated { + text-decoration: line-through !important; +} + +.warning { + padding: 1rem; + color: var(--color-warning-text); + background: var(--color-background-warning); +} + +.tsd-kind-project { + color: var(--color-ts-project); +} +.tsd-kind-module { + color: var(--color-ts-module); +} +.tsd-kind-namespace { + color: var(--color-ts-namespace); +} +.tsd-kind-enum { + color: var(--color-ts-enum); +} +.tsd-kind-enum-member { + color: var(--color-ts-enum-member); +} +.tsd-kind-variable { + color: var(--color-ts-variable); +} +.tsd-kind-function { + color: var(--color-ts-function); +} +.tsd-kind-class { + color: var(--color-ts-class); +} +.tsd-kind-interface { + color: var(--color-ts-interface); +} +.tsd-kind-constructor { + color: var(--color-ts-constructor); +} +.tsd-kind-property { + color: var(--color-ts-property); +} +.tsd-kind-method { + color: var(--color-ts-method); +} +.tsd-kind-call-signature { + color: var(--color-ts-call-signature); +} +.tsd-kind-index-signature { + color: var(--color-ts-index-signature); +} +.tsd-kind-constructor-signature { + color: var(--color-ts-constructor-signature); +} +.tsd-kind-parameter { + color: var(--color-ts-parameter); +} +.tsd-kind-type-literal { + color: var(--color-ts-type-literal); +} +.tsd-kind-type-parameter { + color: var(--color-ts-type-parameter); +} +.tsd-kind-accessor { + color: var(--color-ts-accessor); +} +.tsd-kind-get-signature { + color: var(--color-ts-get-signature); +} +.tsd-kind-set-signature { + color: var(--color-ts-set-signature); +} +.tsd-kind-type-alias { + color: var(--color-ts-type-alias); +} + +/* if we have a kind icon, don't color the text by kind */ +.tsd-kind-icon ~ span { + color: var(--color-text); +} + +* { + scrollbar-width: thin; + scrollbar-color: var(--color-accent) var(--color-icon-background); +} + +*::-webkit-scrollbar { + width: 0.75rem; +} + +*::-webkit-scrollbar-track { + background: var(--color-icon-background); +} + +*::-webkit-scrollbar-thumb { + background-color: var(--color-accent); + border-radius: 999rem; + border: 0.25rem solid var(--color-icon-background); +} + +/* mobile */ +@media (max-width: 769px) { + .tsd-widget.options, + .tsd-widget.menu { + display: inline-block; + } + + .container-main { + display: flex; + } + html .col-content { + float: none; + max-width: 100%; + width: 100%; + } + html .col-sidebar { + position: fixed !important; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + z-index: 1024; + top: 0 !important; + bottom: 0 !important; + left: auto !important; + right: 0 !important; + padding: 1.5rem 1.5rem 0 0; + width: 75vw; + visibility: hidden; + background-color: var(--color-background); + transform: translate(100%, 0); + } + html .col-sidebar > *:last-child { + padding-bottom: 20px; + } + html .overlay { + content: ""; + display: block; + position: fixed; + z-index: 1023; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.75); + visibility: hidden; + } + + .to-has-menu .overlay { + animation: fade-in 0.4s; + } + + .to-has-menu .col-sidebar { + animation: pop-in-from-right 0.4s; + } + + .from-has-menu .overlay { + animation: fade-out 0.4s; + } + + .from-has-menu .col-sidebar { + animation: pop-out-to-right 0.4s; + } + + .has-menu body { + overflow: hidden; + } + .has-menu .overlay { + visibility: visible; + } + .has-menu .col-sidebar { + visibility: visible; + transform: translate(0, 0); + display: flex; + flex-direction: column; + gap: 1.5rem; + max-height: 100vh; + padding: 1rem 2rem; + } + .has-menu .tsd-navigation { + max-height: 100%; + } + #tsd-toolbar-links { + display: none; + } + .tsd-navigation .tsd-nav-link { + display: flex; + } +} + +/* one sidebar */ +@media (min-width: 770px) { + .container-main { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); + grid-template-areas: "sidebar content"; + margin: 2rem auto; + } + + .col-sidebar { + grid-area: sidebar; + } + .col-content { + grid-area: content; + padding: 0 1rem; + } +} +@media (min-width: 770px) and (max-width: 1399px) { + .col-sidebar { + max-height: calc(100vh - 2rem - 42px); + overflow: auto; + position: sticky; + top: 42px; + padding-top: 1rem; + } + .site-menu { + margin-top: 1rem; + } +} + +/* two sidebars */ +@media (min-width: 1200px) { + .container-main { + grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax(0, 20rem); + grid-template-areas: "sidebar content toc"; + } + + .col-sidebar { + display: contents; + } + + .page-menu { + grid-area: toc; + padding-left: 1rem; + } + .site-menu { + grid-area: sidebar; + } + + .site-menu { + margin-top: 1rem 0; + } + + .page-menu, + .site-menu { + max-height: calc(100vh - 2rem - 42px); + overflow: auto; + position: sticky; + top: 42px; + } +} diff --git a/Documentation/index.html b/Documentation/index.html new file mode 100644 index 00000000..9d641c97 --- /dev/null +++ b/Documentation/index.html @@ -0,0 +1,40 @@ +azure-deploy

azure-deploy

Build Status

+

Deploy to Azure from Visual Studio Code

Get it on the Visual Studio Code Marketplace!

+

📢 ⛔ ATTENTION!! - Deprecation notice

This extension is being deprecated and will not be supported. Please see details +here.

+
+

This Visual Studio Code extension helps you set up continuous build and +deployment for Azure App Service or for Azure Kubernetes Service without leaving +Visual Studio Code.

+

Configure CI/CD Pipeline Demo

+

To set up a pipeline, choose Deploy to Azure: Configure CI/CD Pipeline from +the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. +The guided workflow will generate a starter YAML file defining the build and +deploy process.

+

You can customize the pipeline using all the features offered by +Azure Pipelines and +GitHub Actions.

+

Once the setup is completed, an automatic CI/CD trigger will fire for every code +push. To set this up, if you have using GitHub as the repository the extension +will ask for a GitHub PAT with repo and will configure GitHub Actions.

+

GitHub PAT scope

+

You can refer to our +tutorial +for more details on the extension.

+

Visual Studio Code collects usage data and sends it to Microsoft to help improve +our products and services. Read our +privacy statement +to learn more. If you don’t wish to send usage data to Microsoft, you can set +the telemetry.enableTelemetry setting to false. Learn more in our +FAQ.

+
    +
  • Failed to determine Azure Repo details from remote url: If you're +configuring a pipeline for a Git repository backed by Azure Repos, ensure +that it has a remote pointing to a valid Azure Repos Git repo URL.
  • +
+

Contributing

See CONTRIBUTING.md if you want to jump in!

+

For TSLint to work in VSCode, run npm install and restart VSCode.

+

Testing framework

For adding test, create test files with extension .test.ts inside +src/configure/test/suite.

+

For running all the tests, use the command npm test.

+
diff --git a/Documentation/media/CONTRIBUTING.md b/Documentation/media/CONTRIBUTING.md new file mode 100644 index 00000000..2ece56d8 --- /dev/null +++ b/Documentation/media/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. For +details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only need +to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. diff --git a/Documentation/media/ghpatpermissions.JPG b/Documentation/media/ghpatpermissions.JPG new file mode 100644 index 0000000000000000000000000000000000000000..742a9a15a7bf075db65728ab1a171d48160193c7 GIT binary patch literal 321615 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%0AVCQmUzLZIH(rDpwU{^TUie4s&2 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 &atOB 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

{Q`nd+;c=H1-&&{HJ`P@7F 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 P72r7IhH-6lCTIQ*RC@}m literal 0 HcmV?d00001 diff --git a/Documentation/modules.html b/Documentation/modules.html new file mode 100644 index 00000000..1562b65d --- /dev/null +++ b/Documentation/modules.html @@ -0,0 +1 @@ +azure-deploy

azure-deploy

From 7fccd6d98468c226b7fd09d0df5ed5848ff4052b Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 28 Aug 2024 09:13:59 +0300 Subject: [PATCH 91/96] --- .github/dependabot.yml | 14 ------ .github/workflows/Dependabot.yml | 45 ----------------- .github/workflows/GitHub.yml | 58 ---------------------- .github/workflows/Node.yml | 85 -------------------------------- 4 files changed, 202 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/Dependabot.yml delete mode 100644 .github/workflows/GitHub.yml delete mode 100644 .github/workflows/Node.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 575fdde6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 -enable-beta-ecosystems: true - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase diff --git a/.github/workflows/Dependabot.yml b/.github/workflows/Dependabot.yml deleted file mode 100644 index 387fece7..00000000 --- a/.github/workflows/Dependabot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Dependabot - -concurrency: - group: Dependabot-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - pull_request: - -jobs: - Approve: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr review --approve "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - Merge: - runs-on: ubuntu-latest - - if: ${{ github.actor == 'dependabot[bot]' }} - - steps: - - uses: dependabot/fetch-metadata@v2.2.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - - - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/GitHub.yml b/.github/workflows/GitHub.yml deleted file mode 100644 index 7b1e399c..00000000 --- a/.github/workflows/GitHub.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: GitHub - -concurrency: - group: GitHub-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - issues: write - pull-requests: write - -on: - issues: - types: [opened] - pull_request: - types: [opened] - -jobs: - Assign: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - steps: - - uses: pozil/auto-assign-issue@v2.0.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: NikolaRHristov - numOfAssignee: 1 diff --git a/.github/workflows/Node.yml b/.github/workflows/Node.yml deleted file mode 100644 index dfdd1814..00000000 --- a/.github/workflows/Node.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Node - -concurrency: - group: Node-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - security-events: write - contents: write - pull-requests: write - -on: - workflow_dispatch: - push: - branches: [Current] - pull_request: - branches: [Current] - workflow_call: - -jobs: - Pre-Publish: - runs-on: ubuntu-latest - - env: - ADBLOCK: true - ASTRO_TELEMETRY_DISABLED: 1 - AUTOMATEDLAB_TELEMETRY_OPTOUT: 1 - AZURE_CORE_COLLECT_TELEMETRY: 0 - CHOOSENIM_NO_ANALYTICS: 1 - DIEZ_DO_NOT_TRACK: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_INTERACTIVE_CLI_TELEMETRY_OPTOUT: 1 - DO_NOT_TRACK: 1 - ET_NO_TELEMETRY: 1 - GATSBY_TELEMETRY_DISABLED: 1 - GATSBY_TELEMETRY_OPTOUT: 1 - GATSBY_TELEMETRY_OPT_OUT: 1 - GRIT_TELEMETRY_DISABLED: 1 - HASURA_GRAPHQL_ENABLE_TELEMETRY: false - HINT_TELEMETRY: off - HOMEBREW_NO_ANALYTICS: 1 - INFLUXD_REPORTING_DISABLED: true - ITERATIVE_DO_NOT_TRACK: 1 - NEXT_TELEMETRY_DEBUG: 1 - NEXT_TELEMETRY_DISABLED: 1 - NG_CLI_ANALYTICS: false - NUXT_TELEMETRY_DISABLED: 1 - PIN_DO_NOT_TRACK: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - SAM_CLI_TELEMETRY: 0 - STNOUPGRADE: 1 - STRIPE_CLI_TELEMETRY_OPTOUT: 1 - TELEMETRY_DISABLED: 1 - TERRAFORM_TELEMETRY: 0 - - strategy: - matrix: - node-version: [18, 19, 20] - - steps: - - uses: actions/checkout@v4.1.7 - - - uses: pnpm/action-setup@v4.0.0 - with: - version: 9.3.0 - run_install: | - - recursive: true - args: [ - --link-workspace-packages=true, - --lockfile-only, - --prefer-frozen-lockfile=false, - --shamefully-hoist=false, - --shared-workspace-lockfile=true, - --strict-peer-dependencies=false, - --unsafe-perm=true - ] - - - uses: actions/setup-node@v4.0.3 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: ./pnpm-lock.yaml - - - run: pnpm install - working-directory: . From 820b36b418bd9f7f96c65491ce04b37a8308c17a Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Fri, 30 Aug 2024 09:53:04 +0300 Subject: [PATCH 92/96] --- .config/CredScanSuppressions.json | 9 - .gitattributes | 3 - .gitignore | 5 - .vscodeignore | 19 - CHANGELOG.md | 122 -- CODE_OF_CONDUCT.md | 11 - CONTRIBUTING.md | 18 - Documentation/.nojekyll | 1 - Documentation/assets/custom.css | 54 - Documentation/assets/highlight.css | 22 - Documentation/assets/icons.js | 18 - Documentation/assets/icons.svg | 1 - Documentation/assets/main.js | 60 - Documentation/assets/navigation.js | 1 - Documentation/assets/search.js | 1 - Documentation/assets/style.css | 1448 ---------------- Documentation/index.html | 40 - Documentation/media/CONTRIBUTING.md | 18 - Documentation/media/ghpatpermissions.JPG | Bin 321615 -> 0 bytes Documentation/modules.html | 1 - LICENSE | 21 - README.md | 65 - ReleaseProcess.md | 17 - SECURITY.md | 63 - assets/deployToAzure.png | Bin 2815 -> 0 bytes copyStaticFiles.js | 36 - ghpatpermissions.JPG | Bin 321615 -> 0 bytes package.json | 117 -- resources/configure-cicd-pipeline.gif | Bin 1055754 -> 0 bytes resources/gitHubPatScope.png | Bin 84918 -> 0 bytes src/configure/activate.ts | 43 - src/configure/browse.ts | 100 -- .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 -- src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 -- .../clients/devOps/azureDevOpsClient.ts | 371 ---- .../clients/devOps/serviceConnectionClient.ts | 241 --- .../clients/github/TemplateServiceClient.ts | 112 -- src/configure/clients/github/githubClient.ts | 156 -- .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 --------- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 ----- src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 ---- .../configurers/provisioningConfigurer.ts | 304 ---- .../remoteGitHubWorkflowConfigurer.ts | 247 --- src/configure/helper/AssetHandler.ts | 169 -- src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 --- src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 -- src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 -- .../helper/devOps/serviceConnectionHelper.ts | 123 -- src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 --- src/configure/helper/mustacheHelper.ts | 288 ---- .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 -- .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ----------------- .../helper/templateParameterHelper.ts | 278 --- src/configure/model/Contracts.ts | 294 ---- src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 ---- .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 -- src/configure/resources/constants.ts | 203 --- src/configure/resources/messages.ts | 126 -- src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 ---- .../InputControlProvider.ts | 268 --- .../RepoAnalysisSettingInputProvider.ts | 109 -- .../utilities/DataSourceExpression.ts | 174 -- .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 -- .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 -- .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 -- .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/utilities/templateConverter.ts | 108 -- src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 136 -- src/logger.ts | 20 - syntaxes/yaml.tmLanguage.json | 621 ------- tsconfig.json | 61 - tslint.json | 58 - 144 files changed, 15518 deletions(-) delete mode 100644 .config/CredScanSuppressions.json delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .vscodeignore delete mode 100644 CHANGELOG.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 Documentation/.nojekyll delete mode 100644 Documentation/assets/custom.css delete mode 100644 Documentation/assets/highlight.css delete mode 100644 Documentation/assets/icons.js delete mode 100644 Documentation/assets/icons.svg delete mode 100644 Documentation/assets/main.js delete mode 100644 Documentation/assets/navigation.js delete mode 100644 Documentation/assets/search.js delete mode 100644 Documentation/assets/style.css delete mode 100644 Documentation/index.html delete mode 100644 Documentation/media/CONTRIBUTING.md delete mode 100644 Documentation/media/ghpatpermissions.JPG delete mode 100644 Documentation/modules.html delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 ReleaseProcess.md delete mode 100644 SECURITY.md delete mode 100644 assets/deployToAzure.png delete mode 100644 copyStaticFiles.js delete mode 100644 ghpatpermissions.JPG delete mode 100644 package.json delete mode 100644 resources/configure-cicd-pipeline.gif delete mode 100644 resources/gitHubPatScope.png delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts delete mode 100644 syntaxes/yaml.tmLanguage.json delete mode 100644 tsconfig.json delete mode 100644 tslint.json diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json deleted file mode 100644 index f59b7278..00000000 --- a/.config/CredScanSuppressions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "tool": "Credential Scanner", - "suppressions": [ - { - "placeholder": "GitHubRegistryPassword", - "_justification": "This is an asset type and does not really contain a secret" - } - ] -} diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 13bc9c2e..00000000 --- a/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -# Set default behavior to automatically normalize line endings. -* text=auto - diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 86466ec5..00000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -out -node_modules -.vscode-test/ -*.vsix -.DS_Store diff --git a/.vscodeignore b/.vscodeignore deleted file mode 100644 index 0d7c0e3f..00000000 --- a/.vscodeignore +++ /dev/null @@ -1,19 +0,0 @@ - -.gitattributes -.gitignore -*.sh -.vsts-ci.yml -tsconfig.json -tslint.json -vsc-extension-quickstart.md -.vscode/** -.vscode-test/** -.pipelines/** -examples/** -out/genschema/** -out/test/** -out/testfromserver/** -out/unittest/** -out/**/*.map -src/** -tools/** \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 37e42ac9..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,122 +0,0 @@ -# Change Log - -All notable changes to the Deploy to Azure extension will be documented in this -file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/). -Versioning follows an internal Azure DevOps format that is not compatible with -SemVer. - -## 1.2.3 - -### Updated - -- Moved Simple web app and python linux web app to use remote provisioning. -- Bug fixes -- Removed app id uris being set through the `identifierUris` field while - creating the aad app - -## 1.2.2 - -### Updated - -- Fixed azure pipeline support for Github repository. -- Updated Github PAT permissions needed for workflow commit - -## 1.2.1 - -### Updated - -- Added support for configuring Pipeline remotely in case of .Net and .Net - Core deployments to Web Apps. - -## 1.2.0 - -### Added - -- Integrated with - [Azure Kubernetes Service extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-aks-tools) - to support configure ci/cd on right click of a cluster. - -## 1.1.5 - -### Added - -- Added remote configurer for Github Node WebApp. - -## 1.1.4 - -### Added - -- Added remote configurer for Github AKS workflow. - -## 1.1.3 - -### Added - -- Fixed bugs. - -## 1.1.2 - -### Added - -- Fixed session undefined bug. - -## 1.1.1 - -### Added - -- Improved telemetry for better insights. - -## 1.1.0 - -### Added - -- If not a remote repo, have a provision of creating github repo. -- Added support for selecting the working directory if multiple applications - are there to deploy. - -## 1.0.6 - -### Added - -- Added telemetry for better insights. - -## 1.0.5 - -### Added - -- Added validations on auto generated GitHub secret names. - -## 1.0.4 - -### Added - -- Added support for Repository Analysis for GitHub repositories. - -## 1.0.3 - -### Added - -- Update README.md. - -## 1.0.2 - -### Added - -- Configure CI/CD for Github Workflow for Github Repositories. - -## 1.0.1 - -### Added - -- Merged template view for Windows and Linux WebApps. - -## 1.0.0 - -### Added - -- Initial release -- "Configure CI/CD Pipeline" option in Command Palette (Ctrl+Shift+P) and File - Explorer. This will configure a continuous integration (CI) and deployment - (CD) pipeline to Azure Linux Web App and Function App. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index bb1fb9ac..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,11 +0,0 @@ -# Microsoft Open Source Code of Conduct - -This project has adopted the -[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with - questions or concerns diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 2ece56d8..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -# Contributing - -This project welcomes contributions and suggestions. Most contributions require -you to agree to a Contributor License Agreement (CLA) declaring that you have -the right to, and actually do, grant us the rights to use your contribution. For -details, visit https://cla.microsoft.com. - -When you submit a pull request, a CLA-bot will automatically determine whether -you need to provide a CLA and decorate the PR appropriately (e.g., label, -comment). Simply follow the instructions provided by the bot. You will only need -to do this once across all repos using our CLA. - -This project has adopted the -[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the -[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any -additional questions or comments. diff --git a/Documentation/.nojekyll b/Documentation/.nojekyll deleted file mode 100644 index e2ac6616..00000000 --- a/Documentation/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/Documentation/assets/custom.css b/Documentation/assets/custom.css deleted file mode 100644 index e360ec98..00000000 --- a/Documentation/assets/custom.css +++ /dev/null @@ -1,54 +0,0 @@ -:root { - --dark-color-background: #000; - --dark-color-background-secondary: #000; - --dark-code-background: #040404; - --color-accent: #2463eb; - --light-hl-0: #b58900; - --light-hl-1: #d33682; - --light-hl-2: #dc322f; - --light-hl-3: #2aa198; - --light-hl-4: #859900; - --dark-hl-0: #ffdd00; - --dark-hl-1: #ff66ff; - --dark-hl-2: #ff4444; - --dark-hl-3: #44ffff; - --dark-hl-4: #44ff44; -} - -body #tsd-search .field label { - left: 50%; - margin-left: -20px; - z-index: 1; - text-align: center; -} - -body #tsd-search.has-focus .field label { - display: none; -} - -body #tsd-search .field input { - z-index: 2; -} - -body pre, -body .tsd-page-toolbar, -body .tsd-generator { - border: none; -} - -body .tsd-navigation a, -body .tsd-navigation summary > span, -body .tsd-page-navigation a { - padding: 0.5rem; - border-radius: 8px; -} - -body .tsd-description .tsd-signatures .tsd-signature, -body .tsd-signature, -body .tsd-signatures .tsd-signature, -body .tsd-typography td, -body .tsd-typography th, -body code.tsd-tag { - border-radius: 12px; - border-width: 2px; -} diff --git a/Documentation/assets/highlight.css b/Documentation/assets/highlight.css deleted file mode 100644 index 5674cf39..00000000 --- a/Documentation/assets/highlight.css +++ /dev/null @@ -1,22 +0,0 @@ -:root { - --light-code-background: #FFFFFF; - --dark-code-background: #1E1E1E; -} - -@media (prefers-color-scheme: light) { :root { - --code-background: var(--light-code-background); -} } - -@media (prefers-color-scheme: dark) { :root { - --code-background: var(--dark-code-background); -} } - -:root[data-theme='light'] { - --code-background: var(--light-code-background); -} - -:root[data-theme='dark'] { - --code-background: var(--dark-code-background); -} - -pre, code { background: var(--code-background); } diff --git a/Documentation/assets/icons.js b/Documentation/assets/icons.js deleted file mode 100644 index e88e8ca7..00000000 --- a/Documentation/assets/icons.js +++ /dev/null @@ -1,18 +0,0 @@ -(function() { - addIcons(); - function addIcons() { - if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons); - const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); - svg.innerHTML = `""`; - svg.style.display = "none"; - if (location.protocol === "file:") updateUseElements(); - } - - function updateUseElements() { - document.querySelectorAll("use").forEach(el => { - if (el.getAttribute("href").includes("#icon-")) { - el.setAttribute("href", el.getAttribute("href").replace(/.*#/, "#")); - } - }); - } -})() \ No newline at end of file diff --git a/Documentation/assets/icons.svg b/Documentation/assets/icons.svg deleted file mode 100644 index e371b8b5..00000000 --- a/Documentation/assets/icons.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Documentation/assets/main.js b/Documentation/assets/main.js deleted file mode 100644 index 21a5d74d..00000000 --- a/Documentation/assets/main.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -window.translations={"copy":"Copy","copied":"Copied!","normally_hidden":"This member is normally hidden due to your filter settings."}; -"use strict";(()=>{var Pe=Object.create;var ie=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var Re=Object.getPrototypeOf,Me=Object.prototype.hasOwnProperty;var Fe=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var De=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of _e(e))!Me.call(t,i)&&i!==n&&ie(t,i,{get:()=>e[i],enumerable:!(r=Oe(e,i))||r.enumerable});return t};var Ae=(t,e,n)=>(n=t!=null?Pe(Re(t)):{},De(e||!t||!t.__esModule?ie(n,"default",{value:t,enumerable:!0}):n,t));var ue=Fe((ae,le)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,u],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ol?d+=2:a==l&&(n+=r[u+1]*i[d+1],u+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),m=s.str.charAt(1),p;m in s.node.edges?p=s.node.edges[m]:(p=new t.TokenSet,s.node.edges[m]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof ae=="object"?le.exports=n():e.lunr=n()}(this,function(){return t})})()});var se=[];function G(t,e){se.push({selector:e,constructor:t})}var U=class{constructor(){this.alwaysVisibleMember=null;this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){se.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!Ve(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function Ve(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var oe=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var pe=Ae(ue());async function ce(t,e){if(!window.searchData)return;let n=await fetch(window.searchData),r=new Blob([await n.arrayBuffer()]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();t.data=i,t.index=pe.Index.load(i.index),e.classList.remove("loading"),e.classList.add("ready")}function fe(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:t.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{ce(e,t)}),ce(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");i.addEventListener("mouseup",()=>{te(t)}),r.addEventListener("focus",()=>t.classList.add("has-focus")),He(t,i,r,e)}function He(t,e,n,r){n.addEventListener("input",oe(()=>{Ne(t,e,n,r)},200)),n.addEventListener("keydown",i=>{i.key=="Enter"?Be(e,t):i.key=="ArrowUp"?(de(e,n,-1),i.preventDefault()):i.key==="ArrowDown"&&(de(e,n,1),i.preventDefault())}),document.body.addEventListener("keypress",i=>{i.altKey||i.ctrlKey||i.metaKey||!n.matches(":focus")&&i.key==="/"&&(i.preventDefault(),n.focus())}),document.body.addEventListener("keyup",i=>{t.classList.contains("has-focus")&&(i.key==="Escape"||!e.matches(":focus-within")&&!n.matches(":focus"))&&(n.blur(),te(t))})}function te(t){t.classList.remove("has-focus")}function Ne(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;oa.score-o.score);for(let o=0,a=Math.min(10,s.length);o`,d=he(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=` - ${he(l.parent,i)}.${d}`);let m=document.createElement("li");m.classList.value=l.classes??"";let p=document.createElement("a");p.href=r.base+l.url,p.innerHTML=u+d,m.append(p),p.addEventListener("focus",()=>{e.querySelector(".current")?.classList.remove("current"),m.classList.add("current")}),e.appendChild(m)}}function de(t,e,n){let r=t.querySelector(".current");if(!r)r=t.querySelector(n==1?"li:first-child":"li:last-child"),r&&r.classList.add("current");else{let i=r;if(n===1)do i=i.nextElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);else do i=i.previousElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);i?(r.classList.remove("current"),i.classList.add("current")):n===-1&&(r.classList.remove("current"),e.focus())}}function Be(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),te(e)}}function he(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(ee(t.substring(s,o)),`${ee(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(ee(t.substring(s))),i.join("")}var je={"&":"&","<":"<",">":">","'":"'",'"':"""};function ee(t){return t.replace(/[&<>"'"]/g,e=>je[e])}var I=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",ye="mousemove",N="mouseup",J={x:0,y:0},me=!1,ne=!1,qe=!1,D=!1,ve=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(ve?"is-mobile":"not-mobile");ve&&"ontouchstart"in document.documentElement&&(qe=!0,F="touchstart",ye="touchmove",N="touchend");document.addEventListener(F,t=>{ne=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(ye,t=>{if(ne&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(N,()=>{ne=!1});document.addEventListener("click",t=>{me&&(t.preventDefault(),t.stopImmediatePropagation(),me=!1)});var X=class extends I{constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(N,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(F,n=>this.onDocumentPointerDown(n)),document.addEventListener(N,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var re;try{re=localStorage}catch{re={getItem(){return null},setItem(){}}}var Q=re;var ge=document.head.appendChild(document.createElement("style"));ge.dataset.for="filters";var Y=class extends I{constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ge.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } -`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=Q.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){Q.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),this.app.updateIndexVisibility()}};var Z=class extends I{constructor(e){super(e),this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let n=Q.getItem(this.key);this.el.open=n?n==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let r=this.summary.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function Ee(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,xe(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),xe(t.value)})}function xe(t){document.documentElement.dataset.theme=t}var K;function we(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",Le),Le())}async function Le(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();K=t.dataset.base,K.endsWith("/")||(K+="/"),t.innerHTML="";for(let s of i)Se(s,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function Se(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-accordion`:"tsd-accordion";let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.dataset.key=i.join("$"),o.innerHTML='',be(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)Se(u,l,i)}else be(t,r,t.class)}function be(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=K+t.path,n&&(r.className=n),location.pathname===r.pathname&&!r.href.includes("#")&&r.classList.add("current"),t.kind&&(r.innerHTML=``),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Te=document.getElementById("tsd-theme");Te&&Ee(Te);var $e=new U;Object.defineProperty(window,"app",{value:$e});fe();we();})(); -/*! Bundled license information: - -lunr/lunr.js: - (** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - *) - (*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - *) - (*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - *) -*/ diff --git a/Documentation/assets/navigation.js b/Documentation/assets/navigation.js deleted file mode 100644 index e7335e96..00000000 --- a/Documentation/assets/navigation.js +++ /dev/null @@ -1 +0,0 @@ -window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACouOBQApu0wNAgAAAA==" \ No newline at end of file diff --git a/Documentation/assets/search.js b/Documentation/assets/search.js deleted file mode 100644 index 31a4e1af..00000000 --- a/Documentation/assets/search.js +++ /dev/null @@ -1 +0,0 @@ -window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACj2MQQqDMBRE7zLr4MKuzA16ATfioiQjfDD/S0xtQby7pEp384bH25Hts8IPo4No5Bd+x8a8iik82ubRdHCYhHOsGvSVCIdgKVELHKKF92+Ot9YzFMv/5sZcGJ9Xu16LLJxFWek4TiJTfzuBAAAA"; \ No newline at end of file diff --git a/Documentation/assets/style.css b/Documentation/assets/style.css deleted file mode 100644 index 9d619a64..00000000 --- a/Documentation/assets/style.css +++ /dev/null @@ -1,1448 +0,0 @@ -:root { - /* Light */ - --light-color-background: #f2f4f8; - --light-color-background-secondary: #eff0f1; - --light-color-warning-text: #222; - --light-color-background-warning: #e6e600; - --light-color-icon-background: var(--light-color-background); - --light-color-accent: #c5c7c9; - --light-color-active-menu-item: var(--light-color-accent); - --light-color-text: #222; - --light-color-text-aside: #6e6e6e; - --light-color-link: #1f70c2; - --light-color-focus-outline: #3584e4; - - --light-color-ts-keyword: #056bd6; - --light-color-ts-project: #b111c9; - --light-color-ts-module: var(--light-color-ts-project); - --light-color-ts-namespace: var(--light-color-ts-project); - --light-color-ts-enum: #7e6f15; - --light-color-ts-enum-member: var(--light-color-ts-enum); - --light-color-ts-variable: #4760ec; - --light-color-ts-function: #572be7; - --light-color-ts-class: #1f70c2; - --light-color-ts-interface: #108024; - --light-color-ts-constructor: var(--light-color-ts-class); - --light-color-ts-property: var(--light-color-ts-variable); - --light-color-ts-method: var(--light-color-ts-function); - --light-color-ts-call-signature: var(--light-color-ts-method); - --light-color-ts-index-signature: var(--light-color-ts-property); - --light-color-ts-constructor-signature: var(--light-color-ts-constructor); - --light-color-ts-parameter: var(--light-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --light-color-ts-type-parameter: #a55c0e; - --light-color-ts-accessor: var(--light-color-ts-property); - --light-color-ts-get-signature: var(--light-color-ts-accessor); - --light-color-ts-set-signature: var(--light-color-ts-accessor); - --light-color-ts-type-alias: #d51270; - /* reference not included as links will be colored with the kind that it points to */ - --light-color-document: #000000; - - --light-external-icon: url("data:image/svg+xml;utf8,"); - --light-color-scheme: light; - - /* Dark */ - --dark-color-background: #2b2e33; - --dark-color-background-secondary: #1e2024; - --dark-color-background-warning: #bebe00; - --dark-color-warning-text: #222; - --dark-color-icon-background: var(--dark-color-background-secondary); - --dark-color-accent: #9096a2; - --dark-color-active-menu-item: #5d5d6a; - --dark-color-text: #f5f5f5; - --dark-color-text-aside: #dddddd; - --dark-color-link: #00aff4; - --dark-color-focus-outline: #4c97f2; - - --dark-color-ts-keyword: #3399ff; - --dark-color-ts-project: #e358ff; - --dark-color-ts-module: var(--dark-color-ts-project); - --dark-color-ts-namespace: var(--dark-color-ts-project); - --dark-color-ts-enum: #f4d93e; - --dark-color-ts-enum-member: var(--dark-color-ts-enum); - --dark-color-ts-variable: #798dff; - --dark-color-ts-function: #a280ff; - --dark-color-ts-class: #8ac4ff; - --dark-color-ts-interface: #6cff87; - --dark-color-ts-constructor: var(--dark-color-ts-class); - --dark-color-ts-property: var(--dark-color-ts-variable); - --dark-color-ts-method: var(--dark-color-ts-function); - --dark-color-ts-call-signature: var(--dark-color-ts-method); - --dark-color-ts-index-signature: var(--dark-color-ts-property); - --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); - --dark-color-ts-parameter: var(--dark-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --dark-color-ts-type-parameter: #e07d13; - --dark-color-ts-accessor: var(--dark-color-ts-property); - --dark-color-ts-get-signature: var(--dark-color-ts-accessor); - --dark-color-ts-set-signature: var(--dark-color-ts-accessor); - --dark-color-ts-type-alias: #ff6492; - /* reference not included as links will be colored with the kind that it points to */ - --dark-color-document: #ffffff; - - --dark-external-icon: url("data:image/svg+xml;utf8,"); - --dark-color-scheme: dark; -} - -@media (prefers-color-scheme: light) { - :root { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } -} - -@media (prefers-color-scheme: dark) { - :root { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } -} - -html { - color-scheme: var(--color-scheme); -} - -body { - margin: 0; -} - -:root[data-theme="light"] { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); -} - -:root[data-theme="dark"] { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); -} - -*:focus-visible, -.tsd-accordion-summary:focus-visible svg { - outline: 2px solid var(--color-focus-outline); -} - -.always-visible, -.always-visible .tsd-signatures { - display: inherit !important; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - line-height: 1.2; -} - -h1 { - font-size: 1.875rem; - margin: 0.67rem 0; -} - -h2 { - font-size: 1.5rem; - margin: 0.83rem 0; -} - -h3 { - font-size: 1.25rem; - margin: 1rem 0; -} - -h4 { - font-size: 1.05rem; - margin: 1.33rem 0; -} - -h5 { - font-size: 1rem; - margin: 1.5rem 0; -} - -h6 { - font-size: 0.875rem; - margin: 2.33rem 0; -} - -dl, -menu, -ol, -ul { - margin: 1em 0; -} - -dd { - margin: 0 0 0 40px; -} - -.container { - max-width: 1700px; - padding: 0 2rem; -} - -/* Footer */ -footer { - border-top: 1px solid var(--color-accent); - padding-top: 1rem; - padding-bottom: 1rem; - max-height: 3.5rem; -} -footer > p { - margin: 0 1em; -} - -.container-main { - margin: 0 auto; - /* toolbar, footer, margin */ - min-height: calc(100vh - 41px - 56px - 4rem); -} - -@keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } -} -@keyframes fade-in-delayed { - 0% { - opacity: 0; - } - 33% { - opacity: 0; - } - 100% { - opacity: 1; - } -} -@keyframes fade-out-delayed { - 0% { - opacity: 1; - visibility: visible; - } - 66% { - opacity: 0; - } - 100% { - opacity: 0; - } -} -@keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } -} -body { - background: var(--color-background); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", - Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - color: var(--color-text); -} - -a { - color: var(--color-link); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -a.external[target="_blank"] { - background-image: var(--external-icon); - background-position: top 3px right; - background-repeat: no-repeat; - padding-right: 13px; -} -a.tsd-anchor-link { - color: var(--color-text); -} - -code, -pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 0.875rem; - border-radius: 0.8em; -} - -pre { - position: relative; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; - padding: 10px; - border: 1px solid var(--color-accent); -} -pre code { - padding: 0; - font-size: 100%; -} -pre > button { - position: absolute; - top: 10px; - right: 10px; - opacity: 0; - transition: opacity 0.1s; - box-sizing: border-box; -} -pre:hover > button, -pre > button.visible { - opacity: 1; -} - -blockquote { - margin: 1em 0; - padding-left: 1em; - border-left: 4px solid gray; -} - -.tsd-typography { - line-height: 1.333em; -} -.tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-typography .tsd-index-panel h3, -.tsd-index-panel .tsd-typography h3, -.tsd-typography h4, -.tsd-typography h5, -.tsd-typography h6 { - font-size: 1em; -} -.tsd-typography h5, -.tsd-typography h6 { - font-weight: normal; -} -.tsd-typography p, -.tsd-typography ul, -.tsd-typography ol { - margin: 1em 0; -} -.tsd-typography table { - border-collapse: collapse; - border: none; -} -.tsd-typography td, -.tsd-typography th { - padding: 6px 13px; - border: 1px solid var(--color-accent); -} -.tsd-typography thead, -.tsd-typography tr:nth-child(even) { - background-color: var(--color-background-secondary); -} - -.tsd-breadcrumb { - margin: 0; - padding: 0; - color: var(--color-text-aside); -} -.tsd-breadcrumb a { - color: var(--color-text-aside); - text-decoration: none; -} -.tsd-breadcrumb a:hover { - text-decoration: underline; -} -.tsd-breadcrumb li { - display: inline; -} -.tsd-breadcrumb li:after { - content: " / "; -} - -.tsd-comment-tags { - display: flex; - flex-direction: column; -} -dl.tsd-comment-tag-group { - display: flex; - align-items: center; - overflow: hidden; - margin: 0.5em 0; -} -dl.tsd-comment-tag-group dt { - display: flex; - margin-right: 0.5em; - font-size: 0.875em; - font-weight: normal; -} -dl.tsd-comment-tag-group dd { - margin: 0; -} -code.tsd-tag { - padding: 0.25em 0.4em; - border: 0.1em solid var(--color-accent); - margin-right: 0.25em; - font-size: 70%; -} -h1 code.tsd-tag:first-of-type { - margin-left: 0.25em; -} - -dl.tsd-comment-tag-group dd:before, -dl.tsd-comment-tag-group dd:after { - content: " "; -} -dl.tsd-comment-tag-group dd pre, -dl.tsd-comment-tag-group dd:after { - clear: both; -} -dl.tsd-comment-tag-group p { - margin: 0; -} - -.tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; -} -.tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; -} - -.tsd-filter-visibility h4 { - font-size: 1rem; - padding-top: 0.75rem; - padding-bottom: 0.5rem; - margin: 0; -} -.tsd-filter-item:not(:last-child) { - margin-bottom: 0.5rem; -} -.tsd-filter-input { - display: flex; - width: -moz-fit-content; - width: fit-content; - align-items: center; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: pointer; -} -.tsd-filter-input input[type="checkbox"] { - cursor: pointer; - position: absolute; - width: 1.5em; - height: 1.5em; - opacity: 0; -} -.tsd-filter-input input[type="checkbox"]:disabled { - pointer-events: none; -} -.tsd-filter-input svg { - cursor: pointer; - width: 1.5em; - height: 1.5em; - margin-right: 0.5em; - border-radius: 0.33em; - /* Leaving this at full opacity breaks event listeners on Firefox. - Don't remove unless you know what you're doing. */ - opacity: 0.99; -} -.tsd-filter-input input[type="checkbox"]:focus-visible + svg { - outline: 2px solid var(--color-focus-outline); -} -.tsd-checkbox-background { - fill: var(--color-accent); -} -input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { - stroke: var(--color-text); -} -.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { - fill: var(--color-background); - stroke: var(--color-accent); - stroke-width: 0.25rem; -} -.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { - stroke: var(--color-accent); -} - -.settings-label { - font-weight: bold; - text-transform: uppercase; - display: inline-block; -} - -.tsd-filter-visibility .settings-label { - margin: 0.75rem 0 0.5rem 0; -} - -.tsd-theme-toggle .settings-label { - margin: 0.75rem 0.75rem 0 0; -} - -.tsd-hierarchy { - list-style: square; - margin: 0; -} -.tsd-hierarchy .target { - font-weight: bold; -} - -.tsd-full-hierarchy:not(:last-child) { - margin-bottom: 1em; - padding-bottom: 1em; - border-bottom: 1px solid var(--color-accent); -} -.tsd-full-hierarchy, -.tsd-full-hierarchy ul { - list-style: none; - margin: 0; - padding: 0; -} -.tsd-full-hierarchy ul { - padding-left: 1.5rem; -} -.tsd-full-hierarchy a { - padding: 0.25rem 0 !important; - font-size: 1rem; - display: inline-flex; - align-items: center; - color: var(--color-text); -} - -.tsd-panel-group.tsd-index-group { - margin-bottom: 0; -} -.tsd-index-panel .tsd-index-list { - list-style: none; - line-height: 1.333em; - margin: 0; - padding: 0.25rem 0 0 0; - overflow: hidden; - display: grid; - grid-template-columns: repeat(3, 1fr); - column-gap: 1rem; - grid-template-rows: auto; -} -@media (max-width: 1024px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(2, 1fr); - } -} -@media (max-width: 768px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(1, 1fr); - } -} -.tsd-index-panel .tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; -} - -.tsd-flag { - display: inline-block; - padding: 0.25em 0.4em; - border-radius: 4px; - color: var(--color-comment-tag-text); - background-color: var(--color-comment-tag); - text-indent: 0; - font-size: 75%; - line-height: 1; - font-weight: normal; -} - -.tsd-anchor { - position: relative; - top: -100px; -} - -.tsd-member { - position: relative; -} -.tsd-member .tsd-anchor + h3 { - display: flex; - align-items: center; - margin-top: 0; - margin-bottom: 0; - border-bottom: none; -} - -.tsd-navigation.settings { - margin: 1rem 0; -} -.tsd-navigation > a, -.tsd-navigation .tsd-accordion-summary { - width: calc(100% - 0.25rem); - display: flex; - align-items: center; -} -.tsd-navigation a, -.tsd-navigation summary > span, -.tsd-page-navigation a { - display: flex; - width: calc(100% - 0.25rem); - align-items: center; - padding: 0.25rem; - color: var(--color-text); - text-decoration: none; - box-sizing: border-box; -} -.tsd-navigation a.current, -.tsd-page-navigation a.current { - background: var(--color-active-menu-item); -} -.tsd-navigation a:hover, -.tsd-page-navigation a:hover { - text-decoration: underline; -} -.tsd-navigation ul, -.tsd-page-navigation ul { - margin-top: 0; - margin-bottom: 0; - padding: 0; - list-style: none; -} -.tsd-navigation li, -.tsd-page-navigation li { - padding: 0; - max-width: 100%; -} -.tsd-navigation .tsd-nav-link { - display: none; -} -.tsd-nested-navigation { - margin-left: 3rem; -} -.tsd-nested-navigation > li > details { - margin-left: -1.5rem; -} -.tsd-small-nested-navigation { - margin-left: 1.5rem; -} -.tsd-small-nested-navigation > li > details { - margin-left: -1.5rem; -} - -.tsd-page-navigation-section { - margin-left: 10px; -} -.tsd-page-navigation-section > summary { - padding: 0.25rem; -} -.tsd-page-navigation-section > div { - margin-left: 20px; -} -.tsd-page-navigation ul { - padding-left: 1.75rem; -} - -#tsd-sidebar-links a { - margin-top: 0; - margin-bottom: 0.5rem; - line-height: 1.25rem; -} -#tsd-sidebar-links a:last-of-type { - margin-bottom: 0; -} - -a.tsd-index-link { - padding: 0.25rem 0 !important; - font-size: 1rem; - line-height: 1.25rem; - display: inline-flex; - align-items: center; - color: var(--color-text); -} -.tsd-accordion-summary { - list-style-type: none; /* hide marker on non-safari */ - outline: none; /* broken on safari, so just hide it */ -} -.tsd-accordion-summary::-webkit-details-marker { - display: none; /* hide marker on safari */ -} -.tsd-accordion-summary, -.tsd-accordion-summary a { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - - cursor: pointer; -} -.tsd-accordion-summary a { - width: calc(100% - 1.5rem); -} -.tsd-accordion-summary > * { - margin-top: 0; - margin-bottom: 0; - padding-top: 0; - padding-bottom: 0; -} -.tsd-accordion .tsd-accordion-summary > svg { - margin-left: 0.25rem; - vertical-align: text-top; -} -.tsd-index-content > :not(:first-child) { - margin-top: 0.75rem; -} -.tsd-index-heading { - margin-top: 1.5rem; - margin-bottom: 0.75rem; -} - -.tsd-kind-icon { - margin-right: 0.5rem; - width: 1.25rem; - height: 1.25rem; - min-width: 1.25rem; - min-height: 1.25rem; -} -.tsd-kind-icon path { - transform-origin: center; - transform: scale(1.1); -} -.tsd-signature > .tsd-kind-icon { - margin-right: 0.8rem; -} - -.tsd-panel { - margin-bottom: 2.5rem; -} -.tsd-panel.tsd-member { - margin-bottom: 4rem; -} -.tsd-panel:empty { - display: none; -} -.tsd-panel > h1, -.tsd-panel > h2, -.tsd-panel > h3 { - margin: 1.5rem -1.5rem 0.75rem -1.5rem; - padding: 0 1.5rem 0.75rem 1.5rem; -} -.tsd-panel > h1.tsd-before-signature, -.tsd-panel > h2.tsd-before-signature, -.tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: none; -} - -.tsd-panel-group { - margin: 2rem 0; -} -.tsd-panel-group.tsd-index-group { - margin: 2rem 0; -} -.tsd-panel-group.tsd-index-group details { - margin: 2rem 0; -} -.tsd-panel-group > .tsd-accordion-summary { - margin-bottom: 1rem; -} - -#tsd-search { - transition: background-color 0.2s; -} -#tsd-search .title { - position: relative; - z-index: 2; -} -#tsd-search .field { - position: absolute; - left: 0; - top: 0; - right: 2.5rem; - height: 100%; -} -#tsd-search .field input { - box-sizing: border-box; - position: relative; - top: -50px; - z-index: 1; - width: 100%; - padding: 0 10px; - opacity: 0; - outline: 0; - border: 0; - background: transparent; - color: var(--color-text); -} -#tsd-search .field label { - position: absolute; - overflow: hidden; - right: -40px; -} -#tsd-search .field input, -#tsd-search .title, -#tsd-toolbar-links a { - transition: opacity 0.2s; -} -#tsd-search .results { - position: absolute; - visibility: hidden; - top: 40px; - width: 100%; - margin: 0; - padding: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -#tsd-search .results li { - background-color: var(--color-background); - line-height: initial; - padding: 4px; -} -#tsd-search .results li:nth-child(even) { - background-color: var(--color-background-secondary); -} -#tsd-search .results li.state { - display: none; -} -#tsd-search .results li.current:not(.no-results), -#tsd-search .results li:hover:not(.no-results) { - background-color: var(--color-accent); -} -#tsd-search .results a { - display: flex; - align-items: center; - padding: 0.25rem; - box-sizing: border-box; -} -#tsd-search .results a:before { - top: 10px; -} -#tsd-search .results span.parent { - color: var(--color-text-aside); - font-weight: normal; -} -#tsd-search.has-focus { - background-color: var(--color-accent); -} -#tsd-search.has-focus .field input { - top: 0; - opacity: 1; -} -#tsd-search.has-focus .title, -#tsd-search.has-focus #tsd-toolbar-links a { - z-index: 0; - opacity: 0; -} -#tsd-search.has-focus .results { - visibility: visible; -} -#tsd-search.loading .results li.state.loading { - display: block; -} -#tsd-search.failure .results li.state.failure { - display: block; -} - -#tsd-toolbar-links { - position: absolute; - top: 0; - right: 2rem; - height: 100%; - display: flex; - align-items: center; - justify-content: flex-end; -} -#tsd-toolbar-links a { - margin-left: 1.5rem; -} -#tsd-toolbar-links a:hover { - text-decoration: underline; -} - -.tsd-signature { - margin: 0 0 1rem 0; - padding: 1rem 0.5rem; - border: 1px solid var(--color-accent); - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; -} - -.tsd-signature-keyword { - color: var(--color-ts-keyword); - font-weight: normal; -} - -.tsd-signature-symbol { - color: var(--color-text-aside); - font-weight: normal; -} - -.tsd-signature-type { - font-style: italic; - font-weight: normal; -} - -.tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - list-style-type: none; -} -.tsd-signatures .tsd-signature { - margin: 0; - border-color: var(--color-accent); - border-width: 1px 0; - transition: background-color 0.1s; -} -.tsd-signatures .tsd-index-signature:not(:last-child) { - margin-bottom: 1em; -} -.tsd-signatures .tsd-index-signature .tsd-signature { - border-width: 1px; -} -.tsd-description .tsd-signatures .tsd-signature { - border-width: 1px; -} - -ul.tsd-parameter-list, -ul.tsd-type-parameter-list { - list-style: square; - margin: 0; - padding-left: 20px; -} -ul.tsd-parameter-list > li.tsd-parameter-signature, -ul.tsd-type-parameter-list > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; -} -ul.tsd-parameter-list h5, -ul.tsd-type-parameter-list h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} -.tsd-sources { - margin-top: 1rem; - font-size: 0.875em; -} -.tsd-sources a { - color: var(--color-text-aside); - text-decoration: underline; -} -.tsd-sources ul { - list-style: none; - padding: 0; -} - -.tsd-page-toolbar { - position: sticky; - z-index: 1; - top: 0; - left: 0; - width: 100%; - color: var(--color-text); - background: var(--color-background-secondary); - border-bottom: 1px var(--color-accent) solid; - transition: transform 0.3s ease-in-out; -} -.tsd-page-toolbar a { - color: var(--color-text); - text-decoration: none; -} -.tsd-page-toolbar a.title { - font-weight: bold; -} -.tsd-page-toolbar a.title:hover { - text-decoration: underline; -} -.tsd-page-toolbar .tsd-toolbar-contents { - display: flex; - justify-content: space-between; - height: 2.5rem; - margin: 0 auto; -} -.tsd-page-toolbar .table-cell { - position: relative; - white-space: nowrap; - line-height: 40px; -} -.tsd-page-toolbar .table-cell:first-child { - width: 100%; -} -.tsd-page-toolbar .tsd-toolbar-icon { - box-sizing: border-box; - line-height: 0; - padding: 12px 0; -} - -.tsd-widget { - display: inline-block; - overflow: hidden; - opacity: 0.8; - height: 40px; - transition: - opacity 0.1s, - background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-widget:hover { - opacity: 0.9; -} -.tsd-widget.active { - opacity: 1; - background-color: var(--color-accent); -} -.tsd-widget.no-caption { - width: 40px; -} -.tsd-widget.no-caption:before { - margin: 0; -} - -.tsd-widget.options, -.tsd-widget.menu { - display: none; -} -input[type="checkbox"] + .tsd-widget:before { - background-position: -120px 0; -} -input[type="checkbox"]:checked + .tsd-widget:before { - background-position: -160px 0; -} - -img { - max-width: 100%; -} - -.tsd-anchor-icon { - display: inline-flex; - align-items: center; - margin-left: 0.5rem; - vertical-align: middle; - color: var(--color-text); -} - -.tsd-anchor-icon svg { - width: 1em; - height: 1em; - visibility: hidden; -} - -.tsd-anchor-link:hover > .tsd-anchor-icon svg { - visibility: visible; -} - -.deprecated { - text-decoration: line-through !important; -} - -.warning { - padding: 1rem; - color: var(--color-warning-text); - background: var(--color-background-warning); -} - -.tsd-kind-project { - color: var(--color-ts-project); -} -.tsd-kind-module { - color: var(--color-ts-module); -} -.tsd-kind-namespace { - color: var(--color-ts-namespace); -} -.tsd-kind-enum { - color: var(--color-ts-enum); -} -.tsd-kind-enum-member { - color: var(--color-ts-enum-member); -} -.tsd-kind-variable { - color: var(--color-ts-variable); -} -.tsd-kind-function { - color: var(--color-ts-function); -} -.tsd-kind-class { - color: var(--color-ts-class); -} -.tsd-kind-interface { - color: var(--color-ts-interface); -} -.tsd-kind-constructor { - color: var(--color-ts-constructor); -} -.tsd-kind-property { - color: var(--color-ts-property); -} -.tsd-kind-method { - color: var(--color-ts-method); -} -.tsd-kind-call-signature { - color: var(--color-ts-call-signature); -} -.tsd-kind-index-signature { - color: var(--color-ts-index-signature); -} -.tsd-kind-constructor-signature { - color: var(--color-ts-constructor-signature); -} -.tsd-kind-parameter { - color: var(--color-ts-parameter); -} -.tsd-kind-type-literal { - color: var(--color-ts-type-literal); -} -.tsd-kind-type-parameter { - color: var(--color-ts-type-parameter); -} -.tsd-kind-accessor { - color: var(--color-ts-accessor); -} -.tsd-kind-get-signature { - color: var(--color-ts-get-signature); -} -.tsd-kind-set-signature { - color: var(--color-ts-set-signature); -} -.tsd-kind-type-alias { - color: var(--color-ts-type-alias); -} - -/* if we have a kind icon, don't color the text by kind */ -.tsd-kind-icon ~ span { - color: var(--color-text); -} - -* { - scrollbar-width: thin; - scrollbar-color: var(--color-accent) var(--color-icon-background); -} - -*::-webkit-scrollbar { - width: 0.75rem; -} - -*::-webkit-scrollbar-track { - background: var(--color-icon-background); -} - -*::-webkit-scrollbar-thumb { - background-color: var(--color-accent); - border-radius: 999rem; - border: 0.25rem solid var(--color-icon-background); -} - -/* mobile */ -@media (max-width: 769px) { - .tsd-widget.options, - .tsd-widget.menu { - display: inline-block; - } - - .container-main { - display: flex; - } - html .col-content { - float: none; - max-width: 100%; - width: 100%; - } - html .col-sidebar { - position: fixed !important; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - padding: 1.5rem 1.5rem 0 0; - width: 75vw; - visibility: hidden; - background-color: var(--color-background); - transform: translate(100%, 0); - } - html .col-sidebar > *:last-child { - padding-bottom: 20px; - } - html .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - - .to-has-menu .overlay { - animation: fade-in 0.4s; - } - - .to-has-menu .col-sidebar { - animation: pop-in-from-right 0.4s; - } - - .from-has-menu .overlay { - animation: fade-out 0.4s; - } - - .from-has-menu .col-sidebar { - animation: pop-out-to-right 0.4s; - } - - .has-menu body { - overflow: hidden; - } - .has-menu .overlay { - visibility: visible; - } - .has-menu .col-sidebar { - visibility: visible; - transform: translate(0, 0); - display: flex; - flex-direction: column; - gap: 1.5rem; - max-height: 100vh; - padding: 1rem 2rem; - } - .has-menu .tsd-navigation { - max-height: 100%; - } - #tsd-toolbar-links { - display: none; - } - .tsd-navigation .tsd-nav-link { - display: flex; - } -} - -/* one sidebar */ -@media (min-width: 770px) { - .container-main { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); - grid-template-areas: "sidebar content"; - margin: 2rem auto; - } - - .col-sidebar { - grid-area: sidebar; - } - .col-content { - grid-area: content; - padding: 0 1rem; - } -} -@media (min-width: 770px) and (max-width: 1399px) { - .col-sidebar { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - padding-top: 1rem; - } - .site-menu { - margin-top: 1rem; - } -} - -/* two sidebars */ -@media (min-width: 1200px) { - .container-main { - grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax(0, 20rem); - grid-template-areas: "sidebar content toc"; - } - - .col-sidebar { - display: contents; - } - - .page-menu { - grid-area: toc; - padding-left: 1rem; - } - .site-menu { - grid-area: sidebar; - } - - .site-menu { - margin-top: 1rem 0; - } - - .page-menu, - .site-menu { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - } -} diff --git a/Documentation/index.html b/Documentation/index.html deleted file mode 100644 index 9d641c97..00000000 --- a/Documentation/index.html +++ /dev/null @@ -1,40 +0,0 @@ -azure-deploy

azure-deploy

Build Status

-

Deploy to Azure from Visual Studio Code

Get it on the Visual Studio Code Marketplace!

-

📢 ⛔ ATTENTION!! - Deprecation notice

This extension is being deprecated and will not be supported. Please see details -here.

-
-

This Visual Studio Code extension helps you set up continuous build and -deployment for Azure App Service or for Azure Kubernetes Service without leaving -Visual Studio Code.

-

Configure CI/CD Pipeline Demo

-

To set up a pipeline, choose Deploy to Azure: Configure CI/CD Pipeline from -the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. -The guided workflow will generate a starter YAML file defining the build and -deploy process.

-

You can customize the pipeline using all the features offered by -Azure Pipelines and -GitHub Actions.

-

Once the setup is completed, an automatic CI/CD trigger will fire for every code -push. To set this up, if you have using GitHub as the repository the extension -will ask for a GitHub PAT with repo and will configure GitHub Actions.

-

GitHub PAT scope

-

You can refer to our -tutorial -for more details on the extension.

-

Visual Studio Code collects usage data and sends it to Microsoft to help improve -our products and services. Read our -privacy statement -to learn more. If you don’t wish to send usage data to Microsoft, you can set -the telemetry.enableTelemetry setting to false. Learn more in our -FAQ.

-
    -
  • Failed to determine Azure Repo details from remote url: If you're -configuring a pipeline for a Git repository backed by Azure Repos, ensure -that it has a remote pointing to a valid Azure Repos Git repo URL.
  • -
-

Contributing

See CONTRIBUTING.md if you want to jump in!

-

For TSLint to work in VSCode, run npm install and restart VSCode.

-

Testing framework

For adding test, create test files with extension .test.ts inside -src/configure/test/suite.

-

For running all the tests, use the command npm test.

-
diff --git a/Documentation/media/CONTRIBUTING.md b/Documentation/media/CONTRIBUTING.md deleted file mode 100644 index 2ece56d8..00000000 --- a/Documentation/media/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -# Contributing - -This project welcomes contributions and suggestions. Most contributions require -you to agree to a Contributor License Agreement (CLA) declaring that you have -the right to, and actually do, grant us the rights to use your contribution. For -details, visit https://cla.microsoft.com. - -When you submit a pull request, a CLA-bot will automatically determine whether -you need to provide a CLA and decorate the PR appropriately (e.g., label, -comment). Simply follow the instructions provided by the bot. You will only need -to do this once across all repos using our CLA. - -This project has adopted the -[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the -[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any -additional questions or comments. diff --git a/Documentation/media/ghpatpermissions.JPG b/Documentation/media/ghpatpermissions.JPG deleted file mode 100644 index 742a9a15a7bf075db65728ab1a171d48160193c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321615 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%0AVCQmUzLZIH(rDpwU{^TUie4s&2 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 &atOB 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

{Q`nd+;c=H1-&&{HJ`P@7F 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 P72r7IhH-6lCTIQ*RC@}m diff --git a/Documentation/modules.html b/Documentation/modules.html deleted file mode 100644 index 1562b65d..00000000 --- a/Documentation/modules.html +++ /dev/null @@ -1 +0,0 @@ -azure-deploy

azure-deploy

diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 9e841e7a..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/README.md b/README.md deleted file mode 100644 index b2c7065c..00000000 --- a/README.md +++ /dev/null @@ -1,65 +0,0 @@ -[![Build Status](https://dev.azure.com/mseng/AzureDevOps/_apis/build/status/vscode-deploy-azure-CI)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=9436) - -# Deploy to Azure from Visual Studio Code - -[Get it on the Visual Studio Code Marketplace!](https://marketplace.visualstudio.com/items?itemName=ms-vscode-deploy-azure.azure-deploy) - -# 📢 ⛔ ATTENTION!! - Deprecation notice - -This extension is being deprecated and will not be supported. Please see details -[here](https://github.com/microsoft/vscode-deploy-azure/issues/239). - ---- - -This Visual Studio Code extension helps you set up continuous build and -deployment for Azure App Service or for Azure Kubernetes Service without leaving -Visual Studio Code. - -![Configure CI/CD Pipeline Demo](https://gist.githubusercontent.com/dikhakha/d86193a3195f50d6125ec5b1b033c373/raw/c8e5c1452b068fd01387fcf5627029f9ac8db424/configure-cicd-pipeline.gif) - -To set up a pipeline, choose _Deploy to Azure: Configure CI/CD Pipeline_ from -the command palette (Ctrl/Cmd + Shift + P) or right-click in the file explorer. -The guided workflow will generate a starter YAML file defining the build and -deploy process. - -You can customize the pipeline using all the features offered by -[Azure Pipelines](https://azure.com/pipelines) and -[GitHub Actions.](https://github.com/features/actions/) - -Once the setup is completed, an automatic CI/CD trigger will fire for every code -push. To set this up, if you have using GitHub as the repository the extension -will ask for a GitHub PAT with _repo_ and will configure GitHub Actions. - -![GitHub PAT scope](ghpatpermissions.JPG) - -You can refer to our -[tutorial](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/deploy-to-azure-vscode?view=azure-devops) -for more details on the extension. - -## Telemetry - -Visual Studio Code collects usage data and sends it to Microsoft to help improve -our products and services. Read our -[privacy statement](https://go.microsoft.com/fwlink/?LinkID=528096&clcid=0x409) -to learn more. If you don’t wish to send usage data to Microsoft, you can set -the `telemetry.enableTelemetry` setting to `false`. Learn more in our -[FAQ](https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting). - -## Troubleshooting failures - -- **Failed to determine Azure Repo details from remote url**: If you're - configuring a pipeline for a Git repository backed by Azure Repos, ensure - that it has a remote pointing to a valid Azure Repos Git repo URL. - -# Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to jump in! - -For TSLint to work in VSCode, run `npm install` and restart VSCode. - -# Testing framework - -For adding test, create test files with extension `.test.ts` inside -src/configure/test/suite. - -For running all the tests, use the command `npm test`. diff --git a/ReleaseProcess.md b/ReleaseProcess.md deleted file mode 100644 index 3e429d7f..00000000 --- a/ReleaseProcess.md +++ /dev/null @@ -1,17 +0,0 @@ -**Process for releasing a new version of VSCode extension - Deploy to Azure** - -1. Update the new version in package.json and package-lock.json -2. Add concise description of the changes in the new version in ChangeLog.md and - make changes in README.(if required). -3. Create a release branch for every major version update. Example, for version - v1,v2,v3, create new branch : releases/v1, releases/v2, releases/v3. -4. Run the - [pipeline](https://dev.azure.com/mseng/AzureDevOps/_build?definitionId=9571&_a=summary) - with the release branch created. -5. Download the artifacts and get the - [BVT testing](https://drive.google.com/file/d/1vLZ1I-LObjnV-6L3CPOSll1gbH4TJwA-/view?usp=sharing) - done using the corresponding Vsix with the vendor team. -6. Create a tag for the corresponding version, using - [Draft a new release](https://github.com/microsoft/vscode-deploy-azure/releases). -7. Upload the VSIX at the - [marketplace](https://marketplace.visualstudio.com/manage/publishers/ms-vscode-deploy-azure?noPrompt=true). diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 4fe08faf..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,63 +0,0 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, -which includes all source code repositories managed through our GitHub -organizations, which include [Microsoft](https://github.com/Microsoft), -[Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), -[AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and -[our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned -repository that meets Microsoft's -[Microsoft's definition of a security vulnerability]() -of a security vulnerability, please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at -[https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to -[secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your -message with our PGP key; please download it from the the -[Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, -please follow up via email to ensure we received your original message. -Additional information can be found at -[microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can -provide) to help us better understand the nature and scope of the possible -issue: - -- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, - etc.) -- Full paths of source file(s) related to the manifestation of the issue -- The location of the affected source code (tag/branch/commit or direct URL) -- Any special configuration required to reproduce the issue -- Step-by-step instructions to reproduce the issue -- Proof-of-concept or exploit code (if possible) -- Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a -higher bounty award. Please visit our -[Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more -details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of -[Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - diff --git a/assets/deployToAzure.png b/assets/deployToAzure.png deleted file mode 100644 index 9a51e2ed4e692b8274ca1307374f5a866c31ef34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2815 zcmbW3`9ISS9LGOfGRzz?BFBhaa}>Ugp%Eb)bA{Y-GBe{lha6XKoDR5as{?0A^}pXm#R*|HQ_6a$EJ> zdrpi!$iyKS0FY+?3G_@iv;3q41zQ;#09Ab=3nzi)rao350BTdAhwi5VfFs@1P~Rp3 zw48_af!pzSRMX1XVK-unTkz*D4$9XvmaYj7ImeH?x!9Gddu}Z85M|L@4tI7aye1+{sJ{SX21R5_}sUF^H;;G_}=I_ ze8QUyo(0j@KF_VlOco^KPHOmM6pa{*5JnJ2f7szShR0>&z7W}VqSuM@jx;CSvr(|- z{r#eB?cn~dkvAlJckd{uLmE1qFEcoNT z6fTPTyMb%@tCR=Jtzj$RZhQQjIA&PrI8R&Rq?k!{+UZP|D9hq7aHpzX3fHOF7hf6j zkB--jU&coHAL^=G;1oc)jccjd2R|p$3Rqi2^s@hsM_XV4e^7?`X*x{I?)R3^#QCx z;^D6Fb_kzqV7jAeUa`NA29GVkz>`Irm3Aj2=s)e2qb0z3UvFEOVGTxzJ|pOyHW*1> zD)8V-l@nV{5V6+Sq63m=A35#6HZkM^UA?(cio%CPj5Bv#$i@|EvKP^o-@UgsOE?<* zLyOFe+qouMLo}{~TwBIvh#z%gq8Bhqhwt)eVqN&Ph*_h&rn)HmCLF{W^ZmoA{TsDed=Zd@qDAYTzKaC8Mebz~ zQnG)q(d{``aad@;z+SYo2l%Ymb}F^i?&t0$JbMYn(%FcL708kAmePjOZRV6w3&bUl z%=OI!$fh9yI&shDZF=FtGfZm^{dQ4VdibM@0)1dyl{`!-#Y~W_u!wOJW) zPd+dPUk_DPh8t7z&#HV$}^`b4bh`(Jmnj0PiH@>m)IJq{}x8jRA_J3pX!A6_*P zt;e)@WtesboC=STNfCc)qm)XMxufrAF{KEc1-E8~Oug(D&=*Sgic-%*vU(*TWZ@}F z2+zh41c_R%K=w^S)9vEc-6Pbx@L4Q)sU8F=o9IgcY=XSbfF@*j>gUC(-tau{KNcO| zW3#HoeArtI%*n)xQ#ukx!UUW+(^^d9*a+7G5bLBeVMVXTAB$j4e${Vw@%UjSBlUp_ z;`LhLo6}y@r)<*Q(>Q6;+pj1#9*<84n^@ge|L5Z>I@Z1Cry9A8cLH44)IJ|Qu5blD zBxGn_$p?Rt@bpc*&ea}&`SPh{+h@Db9TO81kw+ z*}CI%OKnOuN%u(g`6}jfnAUal*(Y(zp-zXmm{lfsldt;?8Ku===QzCf*!OFr z82t#r&;YAZbI$c7Uqq}j4`H?UM|Zv;;_@0=_kv$ZgZH~!of<{ef3kO!?mAzN--(ji zlrEw}r&u?&sMw7}iMn8Srp(y3L%YS~5kgt^kruQoTnHgY;MsNctlt_>&C|DJM!mSR z{jSn?hGoFqaNqdTa;9Q1OSLyt*6&qY?W@>Zj7)_YmO_pCCZKf=9=6pd&8%`|lWu?Y z+DGagdzu(Mt9Zd{A(XM*7Q(4a2iE|)zxC?HH8VuLexaaW5=2l^oL|{mZkqFIfl9;` z=L`l#D`YaGv?DEDxKY(~eK!fc-^Xw1+}Rr(dOz@M!V)xo@jDs^EmU8e1cp!H$ccZC z_@e%$--Kp#Pr1bza00dL<+Iy5gl@G8<&q)~T*z+D)mh}9X2$~0-djbm!=)*a7b|~) zKN?A^1vYvv4xn(h>KVC!Q+G{-xuw{pbq|ML{Y}=5?N@sdpn?^TzrpjrXvr|ockkU6 zOK+PBead}>dJy)7=BQC?kqXiRaaJ}Y!;)6e&GQ})z6mjs=%GXRCgpdt^Ya0uw=n#4 zG`*q7kQT};6if5%StCS_(ZK^Xa)SqBN4}Jov~i)v`qX{SrD7R^XJq!=b$?Rz*=0|L z5aUpE#5-VfHA*<3=>o53vW|H6n4H5P>Q$(b;~NT9Wld#SkLdCXHTwL1Z}>%tWU z?3*xk6aw~xJoIE9q^;hl%H-9}C+yC*IT0y$f@zUaQMOYn9hBsNvto%4G~cPRb&i6a zb{U}`FWjU;7Vx;<^EdJkp38O=0pKk#REd?|T7k^;v|Q|8vSXhJP8n1k<3@Z7w~{G{ zoVwP_XM_X>T{s>sF~<@j3U!r~Cfb4p=#EKO$A>{)huIcB9-xx4I<{^VJvWfguqDf_ zLySBrpz`oru>6-46-Mw3?tEwZF6{RpxiBJIm0EUdTgem|44}}q#kP)FJabxx@006p)rMS4V zjJPkiKM0W7e8B9RmLJvxiDl+;yaOuEHZOYz!%XkV%XAj>@@Ir z0?j2GOOm*Z%?$YmN2n1P?^>cw&Z7~MlU*J0J}}se!5$wmt_!U5xW8udUFRgEd4mBH zmixnBJxf>sk5jOoJ`%{*HdaK@H}DoPR3dQgB5|zBgS?K8lYk+SHziMRIP$XBvht{7 z$mJWulh}7L03ZR=u}GO>FuVx`(5gkANB|H)5B18RNBD$?FK$B~4kIQg9$Gu=k%kH` zyKL~w==EUf#Q?-x`m_sv0G#5Nfbmd&Q^eijM64EyMdAWT;3D7(M4SB_Mi8MAb~f{Xv$@ zGd^0W(fH0OlgN4}qJf27mA1@096i0T{Z+*vMAjaorZk^Tl!Jgw8$eK;P8RnAua~-P zyO+c1pu{Xi~JGUCE}S|KX1_Y%ziP*uzB#_RC_o1M;<9UWC@Ccc$^jg4hYb4N)L4t0&gzHXxK_fT%ipK?RRgPh9C~ej=dp;nl;5B5p^(-zP>% zof^-M%Pz|-0{7jU!AnTn8*Az7oTG?xfwby)(psql|n%g*Nj$ ze@3jm#}3zP766vRud1r^i}mIbCcs@z$nrCz0Mdiqd|><785Z4cs1?aCFRYDa5u`IZ z93vQ;0IHEe5)U|kEcEV9IxIA7QHE5&F;m#FHfB)(p%DumjF}Ok7RFqlf)V2a%3Z)q zE-5h#ZKtIJj2_~AmwuBUe<#`m##)d8yr?uXi7`1%1hq+c6ZskP2Na3!c#DsuGLoO- zZ6u=Tz7q}#7NTnhR){x{&kl|cQtZGxVOomYQ31az?y&AqMdfkM0Jx-1CpYOn?B=Ri zQ1X+Gex@yuJn(Tr(FxSZYnkM~f%k%Gi)|=ioghUw(s_?l+pWjW-QQLcNwlzh3Gf(I27da)tSA=M#nS*l&^pTSddvjzOha3zs5#7BBo2=za_qP*gsbmZiQ zb%r&qzx|M~j@1aA6Rxb)0oDso+*porvM^^A6*A|Y=5kHiO&d%fx_EoB3B?$Q7>ZRD z(%f`YHN(zFcRSV!4!j>#E_|-Q%&T z${C?TZ?#6LxI7*)Rt;7|`@z$V|KA{?u02AgI)sxDo(<7k)?*%I{z|-tSYVthk*`H2{ zOxSw;BaEaE<6p$jQuEBm%rDKSM;p@hIgi;J+2Ytz(yF*XmTP8Rb;u2aHCkqlBl*(_ z#)KC1HF{>AD_8D6D586YOx3G(v{p6DHNI=emNRQqYP8K^&dJR6&3RXzFDu(FaBFjy z+oanz+cMiqEss@K*0h;Q)tD|vp3W^~)p&!?jdDynI@{M?{{+{-jpq&K^>1cVt+Ed~ z{x(hC=AzBVS*D-244yUv&nymWpXeR>{6%oRbo<_9<6!wg_WhB-7yde{0|m`=#)0~Y z`u^KZw!P{DgbG!Z6ld(i@am%ehQXoV zXzjAe|E zyGcWI!@=S6A?{KhlJapDQ6D8fOR~hZ{^i(5@tAErQxPsOkF|=-m!y`cjP}AkC1#GZ zBaVqBopGtkw!Wxd&C-er5QP?@HY_j*VJDM^K2*!}T15v%o!%`WWbpHxz zjHHN^!#StnqoGesPjpR~PApGc{~1zLA#F(};BzukL!hdlMqP?wSy;DIcWNoL-Q8bF zI{*DF*&xBsw6*7 z7h><3^r%m85h64qvds{_Rt|b)lf<`uYEdKp$U@*Q)0E(vpvm{0FT-hVw}0FtS*hVd^&%r!X72#_j;wfj8-qFMnTzj{Xn{YMj}-7jm?+*DV4|I zD`R6LW3x>N{a-aq`PmGHEHB6O>pIElY`jo{7fzBKmee)D9;^NpLLk`5+%7G2WGHi1 zaM}Fsd6C4Ka_=NlE-ORee%_>U3$M?9@8^hhroFKL*z*8L;#pZOU!Rio&!0~JuABl2^G|pa&0MgdY|=Z^xaH7C$6#> zZ!~Z#JzAY^hMLtY)PI(*Rb)3k>HPse7IDpR4RM{~P2yo#+s?D-LM*d9R&R&mhuV%u z=U8>#?1CM7l4H6)So5UWGc4aY)_%RNWPYc6RCZE6)QH`PZ|B?0?75tlvj9@J=UFvq zc)7+rjJ?ac6wod6Eh~3VJJrz%o};tocP~C~Z>4on60fvA{n0kkW(MgL-fds^AA5N0 ze=T_#MOr|z@~?rIy@>XAP4O4n>FB$+HMO@<)aRW}l!%YUyv85_fdZ}D5wqWi3c{pP zNDD|a{435qCNHyTwAJP#PjKQgXt~#g`0jS$|rOK}7#{?3-N~cmAAmiJ% zYQt8TlF+Q9rZHPsBQl%2t_xY%jH8n5_vp&NxUQmil0U**(xVaW1w-zAeXB-c$hlxI zwAbe6Tk@*TIRpoc8euHbE84BgLXgi9Gt}Mn9lUp&VBUiB+r#~mw;P3&B{xvoPu~zY z#iM`*MOH-6Lr0XEmW;WA0)PPuBLm=JhyVys2nL#jVLtpX{27K00QawQSO6g05&-`n z97SmU&l3+#|Iqw9hf4?pAVL3OLz71??EhfHqvpc>4~)nJtpkXviOa}9b2U>ZGc!A9 z3wxJEw7PH50u%>nZD#-gpZcE!BcuB90?L2E@{5*>mV!LLsl6?W@mG5jGZqh9hky70 z1U>knpsksUF}a7Wjh!>UhY;nzF!-VHKgFz+|in_(+&Jn>txKxLDfTk^jTj*u>t|MTnB}A3^{7{QEu4JS_iDlAZH^ zngwkj>pwND>?~}o|H~UnD)>(+zp|x=nT?i&r7g72pfZHn**G`_|3&cstNK5Y|0Y#; zHggiUw}n!=2>)NN|A+X$EC0WQ|B|WwUoyFP+5TJRe^vd5RFL(bw*OaO{JW$7RSNBC zVN^lZ|NUyhsFL4iBA_3V*iu623p9rgvwt2qeCQ9|zjG)ITmPfO)+Px65COa zInhVRRPQ4YMx9!vSdDREAkU?vT$P4?u|^kEmtLNzw)a(o)Tn#(2-X3gM6R9`8|13oG#YJkqY{VjAn2bi6Nj(^hKwX zs5O!bnp;{ZzX^AhZQHK+Y-~`ZbGQrdj;ExQX;waSmnHEBMFynI8$Ug!^trrtBgn>+ z!^DuXbEZ-cou0!6zANaTN-ozdb&s>drBys>Tna$~lB(vs!qK~(EX)*x8yj`*TS`tk z-h2)g(cb*`K&Wppp}_mD77Nu}*Iz4+;XmyDNaCUO{rruvcJ_>1=Xfp?mhC(?oxD75 z>CuCW3)+)9mnmPh-uO@M)r4QyBNM0C>;? zTpx3GIG<#+0-d7wMdD|F=8`#d)1@vTCr3txJx2`$is7g@9A4oaE&Tj&y4tc%Myk(W zUmSLOJcUHonnlpuf!MnLj>9iiflA6>iDbF)XHm=t_;McGW%nYGW>wA5dv+VPWLC`| zemd3hPrxg@74BcU;*r?YbyuzBILHW%=PN~8H6|(}@7amdYrIBvtX6+fssGZ-4nsdW zkEbEX0|ssnC{6I-m1$wf{Wvjw0^iCW>nN^~!OQxq$BtzS754+T-)l8FUegHqJ*Q$* z%S*qb`i#!x9dJljeo>sGw!-UZvAlN+vxk8ex$WN}Hm#}eyp&w%NTuA4K3U@1_Ys%Y z%cIzHO>!sIkafCZcD~f$5PqgqHNkx{@}MuwlY%=j>{ICR zIGt=Eklry9nN-t#??~;44E#YS-3}#f*^4W1d(zt zM;|#7gI!6L-+rxnisrZrjO_G=*MUv$jAp5L&|rfC$S=6DkhvtfYPJVTKc7Cq+rs*E zLdRA3R$uf$Is&c5z}PA(8gc=aEVW0hi1a&z`?J-8Rs@hb#(N&O!YRdv1FH4esN;G2 ziFjiwI?t<}nLK^#@ehxPXAh2RN}L`C$X3&32=!KzGkJ&a3)!=PQf<)Phw5pFOh(j?7QqKB%zSE#jqL?sK6I zlozpk?y83`0}YSV>bw7xfDvVJXP-n>Et zV#6NgU?GqK=(Q1GM9II9V_8K6y~2f8^Fvsl-=)UUeEV=({nYZh9y3!HTD9>wA7z%r z?^>n|vj&-oh^IsqIY=s3PF_oy)uTXNE7m4*(9L^+aRQ%|Yz~FcY^)>@rN6_<-#Cql zr9mCqiBzEaP+ZN>{`P=Zx#*nonYpb3zA9haWFm>XwDQK?lTt$TViIUA5vcP*=8-wJ z?(un&GQ5Cn>1Q4jeSwyU{>DS>^!ViW>$usdm*4G#blN`qOH$0VUejUX_m$oQJW7(( zPW^Sif}Np^93~RI|7lSj#Xl_yl8l z4QS?AO6HJqi^8SHK3!@{8OszZ|6+8#JF1|P|L~IMq%ptfy#JUj6!kEeLCdq;*YEU0 zp)X6oKRcFGK+*kttw8XPGyNMn3kOnsz@6QCyP75V>qu(gZ}6~e;5!7RY{5KV2oP&2 zgUXwGD3wA85_+NQ>veksnmbvLSz7~JbZ!_YeKJEmnr{iW3hgH{t+rqHiz4DGV-V+2 zu?`WD+gW>o2r42SK0l(}Tn>}P6L)ieE^eKVZMcPwL2 z3v4={`Z>($b>cxf-81AvqdPZ(%dEr6)i~N(WzeSjs&IErESJE`?t3MJi8Q6MAL{#@ z#sQvfp%k`e@gxxzyYLU#M;Om82i&?RVN}w7!>hBn@Szgc{FRwRfzub5FT5&Bd z|Kz_ZD1Mu~D*z5=sJCAiZi8br9rCg^7*6Ka)&*|Ev-a0^C zpH9h{%1(@H(r2Yp?~Xt<1jE+I;F9~k9ZJ>3y%j4FrJ;U}+MD3^*00jydYecas5|Zz zm&IqL+}(e!S^Tv|s_3XYrtkfkFj2Co@RE2G`K-Es$iNQVnz~sz`{D{YpLERrkod#! zr=-SHd4L&9REOk`{ths__cR(MLXYL%vy$B{T7c)DBGuMI)c`p zp8TbZh_4!jO3rLA6)4k3Z0VEu_!aCk`VBoPRzWSFyRwj2Es;R1Y{dbdgT;#`%1IG^ z&i#hLnG#0rrZ$&8V$rbUbkA{3sN{MV-$>gov_=tDaCpMrYG&_SAjC%Pxy+9opG|8M z9O}{{Q*lnjVfV--Yx|XVVp*maFF#s`+VDB$m|VBgjTBK`!d{dII`Zwjq}mDjh=y_u zIPeo>&Qdr+cbW}8*t{^hhmZCY)C+e9bBpxvHp;9o`gm=6Ez)1M1^u;~-Oh5KiBeIp z$n&xSfc6|BO?|RvHRDm~lQX{+yq~;J`P2Dqv12mWv{4w$!-^D$R0rH_N9bHJgYq1& zHC%4X3T!PRw{j*QY6>die7}Y{cLoNBPi_6|;7futE;J2q7z$gX=<4emPGK!oXi=1v zoF9SR4~5R5{7W2K$h8XK84;6E@!J1su~iZUvfckJS1B4_v+%-qj z&o$&H(z%(up3tSscGF(5YjgjG9w*I1=14iI_)+LEh1Pj4u@#fV!)e8UFVn~B-dV6WPXw8m(= z`R-wt`^V7iUS_0J<`@j+%6k zP>XwBv#V9)h zIg4au8M2mZ$Q*bztrt-Ehuv<>MLNQr9}V|hN2-qP{)*AU8=^GFUM8; z+6z3Q+wz~tMWr5A*PiPN5Q0qoYSQUar}(*CvpvUD=jZwOs|}+N4L?q#%sF;7XK?yl zQp0K+g;mHWjT|QZpp?A8`3f0n6Y2Op{kLHkM{WC4tZ*bZo9A@GEW~lWoAeNc_p9}u zfTH;y-ke!s=3P^mY4y%FtTT$8hDUDpzz|0~5i72z*E(4P9zitfh+PZCT8kb9qUsIG zU2|+ppXiw{O+6IJ?#Bx@uY*zXXE`#sH~W`I+{=!?#MDd_2kN3c9A`lsq%@Kq?V|yn zI{cbUZYF6fT{2W`Cu8INQCaRICr8Al;q08j#p9xto3w`k_f$l)ywouUPK)c_oyn}o zSm+o7*{Y`2b8(*6ru%i6A#*sSZ;H=~pXx;&fXIKiS6-W`;b?|NuXgpYu;5q3$!D+- zMs*q}JoW|#RN{VRm5ihqKHwx}x}uQPUF3z` zZ*80?QlVxmDtH-qWO1x0STroUx=zD-S?YR*SUkT~#T9#Z^O8&Pw+rLUR1&PSopxr! z8d>%G0sCmJ7IHXmBtOZHmv+6%v%E@&FAL3P&dJ3Vn_@@&Z25pRV?)fY)0xug8>D%d z99%5BAIy(^Pw&GfCJQ~Smwvlu$OhY^R;0ew@7dQAp>}y}2K~Vec67qajSP6KOB=wC zC7{sqQEC2I72+$6_qhE*6bGUC8_{f;@{^0DCER$ZKaY*-By$FjG4qcf{LurZ)~gl* zT|PZ}5+ZGjTGiKg!r~pw5b@Cr`;N!-&zNK;t7c>LBcZGvbd}X`G!CfYm%(s<4<>y< z4MB;Z!hIWueI9t|=HEJ+&7p~Mb9+3eLL_qW_$hz{(H=(~54q1< z^8q;gKBWb!#7N;FH1+$icD;Nf;zH#rxzC~$WKgdxm6j7!nk~~%{Yr%l9MP?_9r)qT z{0Te#Q!*dOLBw0m&mhyF)uS|<7J0$qoE0=$Uzg=V=Bj(+?K=IV@+eL0*}dLcwTe{V z6`y)UyhLi%)oRuVMEw_+uskxj3l36xU)$cLpAWF*>m@?Hs|lwGA*EG=x-2(h6hjF zB~@w|OKV|>D>7+vRPQFjCF#TnJsZ5RKUmo=Jtvned}B_%fBQGX@KA4UYO%hm;!@8=$VE5v3M; z{GbG2UiXvYdlFx2m*K0xTL81Z7FY!S=k8K4p>APefgoXz^nH+`&6It+>pM3|34|RBls6snF$8 z33y&u&7YxVr)RG^6I&L$H**@Ekwp_PwiC!bA9=Uaa zy#U`YvG#62_HOkeQ1t2Gd2f=K5leVtjjwl?Ny}gDyI^O7q&6sqT?nYs57wjQ^yT&x zQtlSoB61>hu!_P;+84n=NVP}q(`upRK!Z#SO^&;yFvuJVh^KbAT=OL#yUWj}@Ok1g z{B_0+*;dUaBM*)0B#w$?iIME^B$!!&$%8e)Jbyp(*5S6U?uy9G^M&T|9XveDIM&8& zg7Ul8w(*CHsCuPl`Nhh&)~A!6v0)#@oIAIr&#!~^SHG*zwhgb#H6Q(8F&^r~Q>Jsb&3lvCa<{_*ZQ7s_!CzLt=)b0epypY&0|)74-RAfi2nN zP3M0Ti|3vrJ3bXjU$7D^r z2W6+vVUxhZ(He*Zw0oJh3x%QMa&zFh&9N*2VaezeRa?$|UFB?!IVhaC)yCaDmOA!$kD!Z( z#eBJ5e2wk($n_avIZO(7kJUzJ4ro>HAt!=&oyA(TtjTM~QXTHq z^J!8HEZ(&*!r|jWZcSC|t=9~dJ{<)b&y^5XA1#5-;>}bwVNE-}vH9O^ab?dOudP#om%QQ|GHi|+GL1Ahy5H7hu2*odd}^mB=y?LoKS#D7=?$LX4p2%XOZ-J-yKWH)|a zS2Vt09;7$|+nyFD(8!cJcLzOoPdjXu_x^MSAY2E3hT8I0u@{F6z*Uc(xOl_7m zkD{Z`d~t?QpU9jp1LpM%saUhWrah?fh$n|yfqmE`3w06UlGp`yLDT2_{QePlq?JTrPfAR zb1Y_bB)>E}o-L`7)gf8xww~#tcqy6+ry7q;$(4-{H$03gaOjWyV_P{uuIAS|KzRU= z@|z^xPKE*HUpk=X0AT`Fem_p8$6KD{Sl}lx44F=A*-1gDM^fO`kJsiA!#nVJwzg}H zerfWrNLb{TI{>zb|Ambnou+BM>$01Ey;90q+n3cM zqhg#l?fWX(V22Gwhj6;i_e*fgzU5v4arAnJcg+F~cTR9Eh%`C}yU9w7Ex+aoEfI~; zu8Co@F-1qu?fyO4W>4MST&S6X&^vka#%ccK4^I>V?SW+lGuPqX%0;wYxcOCjmv4@( zM^&?B%rP1Dbx{~Y&S4Fkpllv*BLzfjyL@4=FZcPRbJxdh7yfLS8Mtl{=sa>u5HpSO z7U6`)SIp+G9BKraKD7~IO9U3ba74l;eq>w!+iciHDB!;Cu2wXv{C<%Gf18C zrI~&std88aO3g4>e#&;*5r#x`iTuq1pL{eoClnt?QFpRa4CmtsV`tQWjP(8ZM^p#9 zuoU!WJ0$7g&h7}wcKCODm%F+!IB1~PQ;1;jpfmofiIeee>@q$I&cF62tfy0$a}*&m zQS77KzW{+h5iZ<`%BILuVn{C|cd5Q(&=HgPkBz;R5MC_iFt8M!U9bUHSxZ} zJRFXLq}slD&HcmOVD+iXe3j_oytjLc>hAne>$U%L;MMMELD@_ZlH08IYIdxCGb5L8 z)>sfe9=(Ptbx&Zn5V09py*m7tUX36I;fx`5)sr(<{qcfimbhypZaL!qK6B?#wU?*S z7`E#p)O<&2pyC#Za1!osJdO0A7BI>d#H}7+#gPeK4CV&0vF`(|%`{-b&C&Ko-I}P` zrh|n98nntTpZXh41sJCRr~80Qugu&Av|A^RP84c+?2YBlETIX17gKMEmUPh3_CU<1 zuYXI+?v^^_N*$5RY(^WF$2Xt9|7GI;+m2+!;E*z^wvho-#Ez`X{VMKIH_#1tDO(>U zuvb4`I<1iW@H8;}Ec%}lwmIlz|5w9cuqDdgJ0C~+?1#1&ZZi#d4j}JzCeJ=n@-GG8 zNfGs{U4x`Wy^rSgc*dwyJCp93u^-|t-*gcY(%o6^;CISJovzq6gLCX)_*9tWr&joT zR#rULJNm;@+3)7Dm9>9@AAbn=8-M*N4sm0sMO>9?0U{?y`qzO7A=f_J{R-UMOJc=@ zaJ+lLfAF?0Uc)?l($)PBC@a7#K8;$Dii&zMzRFL<3P9x;Zi>K1rMLFB=UL*+n%eE) z?yRAd*wKb&BWZFsn+gnk32bs`~LL*P23mBAYD)}a#@V&&(?Tv8|I>%RwA!`I8C|x7f8)lDaD_u1o<@gD2j{FAT zSn`i#bHr(>Nj-Ww(44?n8?bAR3ugPmE8uRV_0=BRA-)7~_N|gB~&{QG=#HiF9nskH`54Rs`rI;il4YSueiD$KAwP!rMql{-30S z{Uh#9b<|p$99=cy;?n5?!1tuH!VPEkBbe*tM%@OUQ^!EZtP%u#-_s-B#KscF&Q}0d z-Ai>E0oiq{a#?=+*W$o}^ujOu&Cl)i2`YGQ+!ny4>?M|_#p^?B&F*Ge2^i;|AGK|> z!5on5t+?imaF{Uy@7agcGJ@#hGIw3d~51qy=vk{eg43CjmCl4p1=ZlQDNxaD!?tzz9grknGBFA2^*#A!jTvl;$-=0uNs; zq2ucQPX4BE!X}s$$2|ge1xd{A#9ot$4A9IZIPG9pO2T*KbgOmjGZriAi^-|NR;D8B zj|oyy8t2PWU;MvY{%hpoXu3^)v($knCcIxMdl49EQbMp8zAM3hvu z1E+;Q21bpKB9%ms+71rsDO~tpnk~K9tWJ3G1_VCywhd^1b&v)b(q`-ivEYSKj!*d0} zUT1$e)>2pu?;d?0QOR0A-1@SShW>WM>JrVPI3`))Ko}L~z_V&V=9X^ujO$X=RC}oi5wkxr;j1)RU4ls z0ES4-6_ynY=v;0ks#GJMm3J$SPlT>9WF=KpZ}FjiZZjH`IWuIZ)-5Nchk>hpzO!S? zWu#z+d7ZW;P9eI*+v=f?&D?AIca_3zZ%JeZ&Fgo~lVnPcoa}7l#>$pCp&~8qw%sww#zGoV{*mGsuz7QS~ z2b)y6EN~eYu>Y}N(bRSOSB@9RN06L!S0r@x)o{IbyClcTNBSPx6C%57+7rTD8|z(( z7dwlLX2VrEj5i3*O5uSZePv&=x=x`SHc?N^I%osHL3Y7sANJnCT7S^qE?mdsuM!wo zw)q6-kM7ZMyHL62JCLPI9S2pbJOV^YE>v^%Z;)Uq@t^w|$0sm66peffFxkC z%@}Msu)HDN(mt4OVysO|t*1gK%QQ34P^2)yGm!>$#hJKr**_Do+-^z-}#7W!+=wbmEOm=Cyy zN!`?*f&Hxw{~S%enhBv0#l65UH|IJc#*|h`Ib{4uH=dRaHx>cQTiYuDC-zgw;b>HhGYt&!= zN6X8!1k73_vPVj%CH+%?*NAY)%>o}4>V;pw$I@GSF319B&($Fa`c7s?aqiRX6kD6s zm}Ki0mK#iZE!QhZZ>|SdI>^@CW8-(a#av)-ha|Hnfrs7o4-A;?a3^;cK+=vn;`kv64E`ltOW6Q@=kLdhp=28aWvNxv#0Xc2IMJcnYa6n_;4@v;E%f5gd;~e|2b$~lh;)ew-Xpj3uBtUY;!M} zHw?p`>uaBC+wEZq@m~{G0lV{BQFiq*7D5OTBw(^}keA&+6vy`vZ0dt5%=9`K7$brq zc6(8Vn{;Qzy8fa06REOq_{UXuXD&@cU?Qgca zP*v)OF=SEyG-@%ZEnQHI{0kNW)@xnoYQ2=bT=l%rV!LTd@-NM^?}#v>>*09s74SDo zWMHP@I$m@822u_Mf#s@Rc*`zgVf>sb0p1%fvi=f5@)MR1B6F_Wq^H$bWI2s?k9@LX z-nUYfZY6^ahexJZyQTz4B+5X+RH`+?n!M{nDqrZJPMhLaUdeQNrZiVmFg%9^ z%m-hNwv!Hwd=UXA3Ge&Ud(*YRn!CL?&n?ByGgvyL>rP^-l@GZ2oryKBv%(b;$DU|G zQb@>XSPK&d&peT^l|sP~`C^wM&A0mFx#N5vs0B!-W5g3@A@lZQ)vN~rt&UdRxmUo+ zk~c`2RV~2a&k-w{QeqPtNhjK(%bgJUux9$)L@ij>w8r9ZRkPetiThcNwOasuw_u}yoJ-SU(?oYH zG=f08x*!n0y_&zcN75AGLkm_a3}bT>5^UOC0wyzT?`F?ipPZor>`H;q5Y;Gdr@Sbh z4uZ}@s7SF;-ZrTk9oMoENXp>35$!nJ3isfdZg?eTQy7iTD|r@IWD--;l?rN>ag3`4 zbZO0-@@EP53-DQVE#RpHK=AEvoWDi4Cmn3HOowKXPhFBna0Uk4ZTRVT(9c-X21|2< zx>pPxKfC3NSc{MgvC;a_;7{aE2w3EfPn3E5q{Rfo<1a0eOeuf^Cx}FSBO1|anlV?+ zkr$fJDONk;Kcd#f3wg(^uanqH^SzDuC7qUF>}*G z1&EPtnT7c5x@wW>riIKLcN}(ygbcgd;n~Uv7xc(v{IBtpsg`e$xFIe?&UPv62qr+$ z&nAXiS~}kaDsLAUEs`;oKplWX@vv@{f1G{AP!@zU8jF8t65JxKgNaQChhc=H*pD04Au;%`_ zI~BkO!;|lrAFf;ur*ts) z^2w^IJD*9`%2m1VhB2u~W&Z<&B!d7(nyL|d@?{b+li=W;joroL$ zK~kc^={ig-+IUt+?$&qVYD4=njrvcD>d3$1U`MFGy@T!F`kP2QBt!p;QRCr97zSy8 z8l%Tk=HZ|H5h)n!Cc1t11I9HeYPlbPO}V${T7$>N0OzUQXP<+6G#p=ef0ieGqZ|Q` z{cptF3r-1#rE#z`FMadtI_=mO?b{^pX1vuqc!G}$L?A>kxpc=FRUP?r%o+4PLZ@Un z4PPFn$4Q74^P%@o>e=(xqrn+ zB|C#l9#|yq_?*9;lFcv>GRW3s=k(N|Oq`s8;Qv%~&hCooy~*^KY8ub2)qVRF z&1^bWXi|X;VX(=fhZ*W-4RTdl`lu%?z$PyJ{+Mdl;@tL$P8sidT=@>}0tW&o0-&kM z534=NbHqT3ttklCJbXYIl!BQO>U#H>g|HAqV20%DzR34c4AG74@tf_XadAvdV6C*K zFzSZS#Ylaz6>&muq)72EL3OiEMZetu`6RkAsUsrLUi)2Bf7|?-u%`FYb~7{papnRI zv>$L!){#FY6szS->4(1lo9(PwUt3KgFI4C`ld3yh*g_EZxWG$i@*>~C||tTamFQU2VCJic5y ztW@d9_QFS=SUethr;aBtA(!k;agQ%8EF{tg!7p=4Fen@eZu25}iq`_UaF?v3H%^k9AMy^>yy& ze#!7iMv`a*`9Dq;m}ItkF&DX1*j%SPx>?YhG?93DDhwMj@tEQbrL?7Zxjul5KfSa# zCQ`c;ka3l3{?vF5wD$V6pKO=@$(E*u3|{U*MAX4!p+iZj5#B`qa*MhHyDFcN>0LN~ zpm-Ay^kuA{-_=4+f#{JxZ05e=1x&)MSNFv;eBKd@#>?&8gpVESpkU9e)d!Acfs}r> zKZkw#Dy;+!PN}e`c-i!EI9G%Q;pOAS;j~%zjvOW)PE&?faw2y*V51n5Vh+2|^@*vR zldfj+7tDB`NSz=C{ua3*&*XIyA*nY4gc~o^cayrb0Ld0kH)PflYwA-QA_+rO3{JlmCx55}!v~rCaWZ6tr4tK5ZuW4!;q0J&x%xWh zl`x+N*MO#gYqSrG1#{=Hw46~io~iJG$F6}`EJ!be{2M!WFbyiXO@rOyiahGY3U0oD zyMehxd&p5cqij+)3A`u*ur*-@{M1<>C5 z=mN8=7S#m1MPwl|2)eZ9I_SRL=h(Halam991;4Z{E9a~dR?xn{b*WZMJ0k7>pu-7# zS*1hz&dalmuWGt~87gr zBdZz1bl>g{uz3-k-M%)^qA4d^FWcMr`?+guVDH7b2U|Ekp4SbYNQ)t58Xx0{&UPJ(=>jO_%--i){|16GfBKr**WFsq1VDPo- z{+=n1O{v)e6}(~(9MGD0&L-J8H32(g?O;vO#7gXXGKsD%z)9!-z!}%lq9BRoIQAjU zNq6?nI?b=%-0IgJ@J$vxx#;Gr$OC&W{W|^W9m$YVMSinrryA_Q(NE} zuFo;8=XjRdBnc7rCiRU0+SM`2Bz%;Q@+m105;n2^Uq1w)p+S# zJQ6<$2XjYZzx{*Pk+KnDQbkan9Y-oubg|h3p<+Do6#8@b)g~($O>75s95_M^(TE?r zI_9m2qBMd?xCi}TpxN2Yur}$pTj(u)a_Tt56_qD)ZrB3HLHu0Nng~@0IWHo_7l?L6Py&N7`;0 zuNfzX(y>{!4W^{V-qRmtu*)kMvUWv@m)^1GuS?aG`%vJ;sc%Hf(|uIJ`c4^gKg;W& z&MiDqbCnUIi32xWKHN0=nBzba>DiZ2Y+izb_38ZDN+_f>9yxpCpiCI~oZNkD;5i~+ z3T2-mqr+oRognQ&x)-XmvuGKEUG1ZWbzre<;LxCYY)isbQ%fS*u8`ML4)%kI#{_T{ zbA-^|Ks5XU10xPskS8%@g7=VrWPAB6N88qV)2%a~&gaL7byly&uz)9wE%cZErtR~z+D>zt5YMXm z!pz<8y#EZA_kqeXxbQ1GjTu(7sB3nosu@tzLI@3f<~xMEQr{_jC=M1ha6oj!mdXf< z;P#@L^KX|<2puxKCI#yMWA3fO>ROt1QCtH|oZu2XNN{%v?(QLYaCf&5Bv^2FCundD z?(PuW-E9w6)+hV_v(C*q7w0BU!U*h5&yb4ek3(1{FYc!;kxEw+Lv3 z19<*gaBvE%SkloFAeUnhD2q6XB$?NQkbuJ_N|VLn*J=f0)WRDL;ME<(5J2E5^K14` z`Mt@)SO!1FS<&6-zh6SUiVCqlSKhN66Io!t`34yok(Wk<2}mOlC=eD1@snqNGfw=k z4*uQGe|2|>gjl4#u~XL^>!tVqcjL>yga{ynFajD#zQVx2WF`FW^nd?#j0_G?=?ShB ztN#0c|MMtl?`2q%NTDq6e@p0pe#6BX5W&e&#kVBj$1- z|J{$a#+N}l2RBc?{Y#|(s~-VefYjj}g-Man{yfO#mq9jhALJVUsRICVJPAliumBIu zEb4!~{6&exCr7{_SCs za|EOW+6xlFee>r*HgN-kba9@Q8v3)8{{Jx*;NnEu0q=3=G$#K7;Q71Vo~aZ-%KX!q z0#u-cFcnT7x)B@Pk4bpluXsv+(LMfy5`|b_Xv{uX?L%75nCfdCf!R9>WJ)>jQK>y{ zPA=MEGjWB@QvR$ykTD1jQv{p^zD%dJR3N+`O7I}zT>w5DvywCy>7T@X!bbw43Gv%! zKc=#WjDoWL(Cw0b5>t!t=Oto*;Oi`lVHyLOfcHigM~(%)WAY+;_^*lcKW9plHC&T@ z*6MVs`^C+v(q~LET+v9vOV3WZdD=hq1293q2!LExUe=B$-aE7MKWpa%<|QWw$&Xg_9~Rd!-plf}CZjmS z{L|6_K`j%%JRoS3Yx<`i0!G{O#e!U0cI7nx!zl4YfCt#&$}s5utOh`D0n}Nm{c*Go z`_puH$F0vixWOp=4^h8r2rPa`ZFA_9XI{vbRAIx^cHIK zkG9D7n!uM)7{kTY6p?BE@BtYwS&y*IruW0V7%o$N?BW0+B50iV7O<|ln2P?kVD zF+ZS%lL(OMR3_|_F~o#QZxScj<<8=?ik;6X>ppuvkk>a}Qn;dZ>xP0OmOqk`UD*jM z-vM=6dNb-}cl_k(_HYB=9ftjl?*sU~Odxx>+|087PDi&?(d|{GtCHvV=Fyz9k62`S z5j~|hf69mMFPSmRy{A8A^oWFxCwSb+1nM<*Ci3M91<$W&oWm$C3*WbU?BORx&6KU^ zk29ckM_^72jq{9L)ourG)5UWCZLXK!Ks-B(fcN@B!J`$#;ejDqLU0I73Wh+02fPHu zR&|I+a~vt%Zcb3ULkW^Q0#UZh;pY;lOqI*yTV0$+9mnenS%ALxGSNK_u}mOB^v%(K8G+tIeKc<&8px z*E&|xJ9oY~n$y=)Xi!d7^Y%{p}juLhzwlpJahrH|L_sPPN*`fJU8|KM--- zf-4ij`?1P-#cRIC0_AYAIa&Y1SAJ{V{&ao@AZKoDkYXE{Y#>S06TmU^+|;{RDSj>x z`caPWc78HOrg^)qDcMgusj2h&wU8gx$?2&A+r&MJ>saB03DsPWgsUh&fze1(UnWw$ zz;e|#!>C|6nZx}3+g#a1KOiqox=`^=J__GWTmSQ~O{qJ_IZ4TA4wB9O#8juFIdR?K zNQIlo4yCOxySoz|&?OI`=%=OnI5x|rOlcN`jR6_>M6lr`ax$a7Sl_|#-;Mf27G|%W zdn?yt8LlZGj^64|xdIdvE|(iB0zNlwGwY8dNr_BG?~9j{RVnyRW2tQNM@G{4^NqY8 zBq(K5^Rj#76#FsysKlq=9@BKu+p4E@jo|tY|>cH zfA_cB>J_4nrX;&5x9NwSB9P5pa%;LA!iLXp`x%*#ONgK zhu$a@X;!8PCoiV1qz$7iaV)7_thM_G$A)j~A$!#hS-(!j&Qo4+K2$kI%-Mc=)0jlG z)^R(NFn-;u@O!IUT_OWfghC`>cZK79J6dkGKn1ta#i5K?A<|F4OOSnaDGwD$#W6r6 zkvrg#{h3N5i=$MhP8VBT3Y%_~KSSeYeFwAV(?lAOl&+t<8}l}id8~<(Up=C0@XUOs zNDxSf(lDusDAi)i27<0yGaQLP?m5zHws8_!y)Ss&(fu9@ntJ^&T@j*&NCN@sGSvnK z$CyLOyHd(~^g0b5aa`92BOgDS@2yl-MIfUBWP)SjoCV=_57z?G7&mGCJI@EXB(|{H z3StYC+w+aAS~@(fF~%B!R;4%h32Dr(?wfn8v`CbBdN31K^Me;t*yM31#RGo3FrS)8 zM95;FnsBCyb!1Yl7r&?G4L>NPCi8>FgHR4+zLJT5&*CLVSlnfPpk=XMm?{!Z@A}|= z-e(xRE0r&P*!c?&>)~6u=6V$DM-TV2f7JrmIIRG0rZPk0M~6uz61sl!4_5JlD?5<@ z&%(FwEphJcwFQFoIFY&OGEHSUN|8@cB)EJ`j1)WKBVL^;casIZB4V3oMpLEsTMRj@ z&o|EtGo^-jVfqa=yG)lm-0G-n6uNw0Tk|`cEb4^IWH;2n}l~zO{^{9rF z8Y>^T2oYZk-(R1IkMB5e{_RyZxkGi}1AYQAkS&2hA_P^V2~i3THQ~DE`BdNTZ9-Bn z0^a{+AfU^nyauYJSSLp9GJ4dfz4NUvku5aBMz&!S6SLQ^k5jKqF{RU)0A+}PlcJGJ zzK^5vC|1AEZGDuDbeV!S*s7MeFjH8GOjhwO%X1=VEVzknGFPjy6LlKB(Vl`wf)0Q_ zH>O2`aU^-!q(L;Oa6=;P<*ns8T=b^{P#A+75!^ zBBqQ$QrE})8OTd_MXslp-^dF;p33cxt@m6^bmU4}bjZ3CCR_6RhBu})w$+KQ-}Mtg zRnv~b1}raescV9gs04Vn44XBls8sql%*#g7o~uZi_oj=?&AbJaGDq6hrXLD5Pqif5 z=3(1@~;p~mK#EnO_{h(<4)e|YMGhee|9nT?I1x!-vqJuSmHzlSgD}f4h=xf)@ zC#L(iIEq1)WO_$z9u;5yVewbs-?H$y#DKA zNLf4OHSDaF3XNh$qJE35&goms6pdF0YHv_`N#Xx?rZdrf86_}$Fu=6J!O$TedTN#6 zoVEjL#&6*16{5bVbpbT6uc4tXs)aWdLn*v<4M9Ny>1kfW!4z_-R*7^6OFvXRV-tX4 zAj`;Rn?zEHj@LRQe!D`=K{6^DakTOIB>s2B=VCHi<3DAR;cwO6YGw7pzj1LT$os6~ zsYYq8TrBi>f2DZ4DgI&!DIox^ST@rmA+y$ekp^T<|L6L;QU#y83WTLPaq<4B;Spcr z$^12KM$xm#xVGGdpe9In=UkRTB~nS~g2L+qcIC^%p51ko6zYv|-0>NMIE8W>HG`== zgq2uV9fZQW6i#NA0bI`da zpqkwrKW?h6sCx~T8~#B3*q{$j7-gEPnH;j)13 zTYd&xVqGtdGw$|JaGE4rs<|d3I{M81$0(nwij>-miEc2Sz&*(42?Gr?DMYw&7CV$80pZ85%L+ko_IE7EJINtty=rN91t zWCn4e!r6;}>j$a&N?@7poUTD4K|Y+?Vfsm7wBdspgBx>rJwSOXWq$r#q|r=cw2nzY zAX~w^en8}@#v;JD@!?)PhN_^mOUT+^z0Fh4Q_0uzv58tZ=%V_euDgi;$2qn_63j~M z<7cr*oT4zbo+8%06QWIjRj*)?AAbd<0s)U$o7KE4gD>9sp-uur9~xgMurTkaC>*F` zve~p0Cy=KWIn-p?c%e!&4=U2nE(_!_S%B=|d+15Wy0yRAHlKmi!BUN=%(6tmUD-t! z)7aAG8bRTwC!X~&RD&;>CaagiaG5uWCBV^-HHnOIA-LYGS41~aP z+epA`#;g3M5&3N=x>yt#<{=&w)5YV(W^rPCMrUr^4TPhfCPHr8hCTGVpo~xm({HbK zXN0>G`5kdSIEaIf4Yt#Z2Ddrx0icTO03ahVBnI_oloPxO#Z} zLxs&LCOS^*!gyUIFc~glR%1@Z(TS|y*gPp7wDz#9_PMpC%AQ%u^@U@}94(hZR zl_sXlRcXEn>Hq5l_@d}ctQXS(X34DqW(W2LobL++LOVG^MMq?u7xP2q2Xe=~U(be} zgZ}40CZIx`Bqn}{pO>c_S}!zn_5Nt0YNZlYfT8aF4nnyx2E*n(Y@w^Q4BOx`D0_OMvySfZ>{?KJdF~ue;^ih&I&41a~WF&G;8W;R#4`AI7%bX1TnyU zcHh^}*Jz2Tdpn#wK#EX(*raje(L6Ai>oa}SPX=bO6DjBTq4tEO1ynmyJuc}<#inVU1hMuc%c9(SL4+?~o@J2$s zd)_V9gZ-Lv6d4QwAM5!OZsugJnU4EWaNfANz^is2I*Nf<`Zb1DAni#S-_i{4q3MQQ zv&O9y(#obb)az&Xdj4s~{x~0kd_8TrU&f%d+;;F$ajPsY>TDUtLOf|ot4(O$P?D6% za9W+6KA}pna>Ut5M+n<#CEBLQZ;zLFk{Dzh3PJoS8oDe6dtUsP3{p&2kP54VW(GrCmuA;#&HdONwL|;6@Z1OeUuj!uI<4k?-do0lt-$v( z2)-C?2Eb@DLPM&RP8A(pVQPA$IPWu4iKM>XQ<3Mu5AeZ|AN8X+XfQaoM)8D=%!$cw ziem)NBqb(ccmq_P@bI3gk3$=l-nMS=oR3&yf&Q(C0%i^o-z5>q&D|;80#9K)uy!Ru z`K2y?Iv40C`tq(3<8w$573kC97NX_=n9~EJW1AJ0LbfQ$K^GXFgL5bZFA;!0JGIzg zDOOQO?BKa;g!;SJR}HyOfSo) z^|4a&cFM!j3|fN0QX+mIWmf%haFU!~Z%8axA-NvR*|TwiM$~V03b0)Ci)Ez8Qw96)%r1NOne? z2gN@)QUw{ck{i}(R{$=A%ElOX?XS&FzgX%f155!7He3*X_6d!fM1XrQnA(uw1WD4> z?uDib#KhW?1z%!yy1KgHcZ4>ud{GD*RmP5##lnP270$+PK7+ZfG~y<6^r*uy-U)1p ze7A345sxFyMn~7;HQMHn^?2>hdnTVpXb$!Jw&ncnQrF2(_VS>4Uiw@&ELar8#AD zh--P&yo4m&YP=@Mnv4;SrV?1wg!A?1;wYK`N4_P#Nb2y{wG2XH`}E{ES~QUN*+oDo zjW$caW0ELVrdo%bH{<(gkSjk!9{)^<659kB>~$snQb!)47Ya!F8Ttqfx_%^vkIWm$ zX-JU!La@AIHwcS_R5D1`Rz@iF#t+bC1CVkv5*Qgnq58&mX#=WwZD`&>bxuay-?Yca zAbV=BK9y?Je&OgqAz50$2EQ*4N%NA>F!Vc6qo^3)l;WPF&?>Ff5b$uIttPx75qxXA zgr?(r`{p6tWG%A5cHI_aQpilVlPIXc#1oLTs?~P$AjP9BX2n3m$dy&1&GS<#gbCyL zYdVnvSNbzZ1QasqGFr8V4x@{shisw3ylli~UMYNnbRj!TJb(GiGO-za_LQ)u%+e`b zQi&KU+e;#&dK~o7xA6g;yVZ}|Yw6(YhcU>g8}Qt*18v%rG0!^t|^dDjf_^abI4KpK)K& z>(slz_f39Q8?8a$D&r+V;Mx7XXh~2>c$2?3yPPU=K6J9y=6A8hakh8n;Pust&FdFu2za_9v1!wFxX_(3wyoz=Y!z*Mf_6~0<6quHvq0V?o-aj%uJ@NfHpoI`Rw?Rx8UcA=Dg4O0GfQ{w%?9UeNmu?1m3oZc zgpwczLIQqQ$**1o_T#f_O{pd<7@Nx3Z7lD6riE(<6X6;&+m=@*ZV6&GE{8B-5|r)wPb4%6pR>QoMPit|4mRFJ%I#x`nPul7YZVT&ewJL+3<-eH zW4TbBQxr$5`KeI?qb-r7Kb_YkjRpovxDTzn!0^5{ws*@FmoQ&E^0oLr`=^}Z2Zewr zphg#s!UOZ(Xl)J0JLQnxNMcX}>ZpkCk0Jv3uXmaLwDDRJxXECSi^njW8cvHC4OBgfDz9<39Q-Mo)$q!L ztIK>6AhA@~MKG=YSbmlEYuzec0oF;~=Z8SIb!%RK3Fa@^Q9pu|?#yRmN)R#Qhp<+_ zFme~z)$LBk2%NOd_)x?<@@kS3`BhXcQCGtwLK!Ybw#FIzsJ8c3qQ^BfMKBCHJyFl8 zfe*stPM1ogW78JJ?2K;~vzRY_EFQ9ng$oXa1JP{LtCu+8*Ly$ve(v;WFN0@wY4Nyl z3p0#c-RMcR<+ttEsu{Q+)UY`EFx;Ll{1TT`WL1#=ev^;kd*5O{#ILHUnbykqmGOMP z3os=U2yB_7Ip_hKB^pfM#bhj{PG(%6m#X8o&LWWAo=6Bk;&$ge_nFkEaSa* zdDy0&AX~J!<3IW61?%WlvQjUa7$%@41PkJs{V=|$1L;LiA)B5HN1BRKuS|6vH&3Y8 z)Ax5wlK6rIlo#SR3R`}TB}i}zfUp?Budfo`eYhF;hz30$yGFk7pxfxA^A&Rb*{2mR zJY@gj6o=k}WAkJ*Bwh({F5vv(1bQ31*7N4SX_t$%>{|In1x9^7MCybk?JCqUv07Gi zJ?t>HSqQzRW+_@-C#NEutSlwEY7Ra@i(Zqt)If)J!-j<0AE|%Nvw0o;Xp{doimmQ- z563|%|AzoL-(`sKZzgi-oHwkD)_%{BP)e&T6aMZIoY`CSG3LW?a55M^IX#AEqDu=Ah?MO8tD&_#Y$u z7{YeOJZi`tUfW^(#tPw5Ux0Olp6=JcpUKoRf1}GT18@N6tWNv!S=7-fYxOy6VqD^1 z;9*-3fM~J_2zBNHyaWS`9HieXmG1?BKQ|;5X;1D^H~$;OhkN|}`W^7%=%-4LKy!_! zhug{c;LM7|@i)I;=v(&%>|oWvN_{x$0V`ix%~Ab@sJ`6KKwAFn*v@z;6K|YeQ{%{X_e!7s?0@uJrEbKcm{fZvi3G``NYrLwnE*Z{`(J zo`dK=sQLe+X+XTzl}T*x#ZPofiqiVjXoO_a{D~2LT2jyyjpu zT(|iy66Wei(o8Ym1A8cnYXuzQu<<`1F6OqB~)%Ij3JH4`4s&r>~tnxxvDOX$;%+3(3a)R>pYCoVRSuUvAXCE*5 z!LJl(-7g>adDBnjDfyF01un(!Vzj?wZhv#t%9wvhVF<(!f9MJ+%D`sOrLu&Wkn;sW zm%U?C3ZP;fi#o4}5CGzww>q{l9f9{ztY16EN~jHQd9>A!YcCkUpq6vM=tTs<+NA!? zUpw)BF{$nNHb4&R&6^M`x}+lb4KQhB0jva)0+IG%oyOg$83UT9Se926hfXHUia&v7U3?94nOL%$r%8XO)qH<#&^x?v?|!sSdwl*_&6n>;N2<^Sf~-l>+HP)%fxw>}{&8pH+piO1$)I zm1P&(^_zih8d54xjvdDUS@(1m+Kag=qdet@x85i1u&S7*=j8*cb}MLS_ms4)%+6z9 z4JjwNcLx-^;~Ji0DCKs`YxZ{s=j;Jq3H}{`NcX3)#;Cx^u4=8ecZw^gscqFA&&u4p zN_Q}~Lo)l7Br>BhJ~~gRvg(G6#J=P8)U5aE2Y7zP_>*Kp%*Zsbx z@3^Ft|Jh;yUJqc@uslR46u{2?>TTD@ml~bvNWq2?*H3zKkQvz-Q*rigGSHy2e}2i{ zWj0X=H&=m!C_@guI#kAeWpbNcCbYRHSwC&YVceGziZz%FV5#?>ZDcEJWa5QV`ByAJ zeF0|fg<`Q>BPndf&l`ONzk*-kN!V`L+M;HG+k#EE?A3-R8Y0V-5KA9ScK0H1(QxinYH7J)|}e}OOLr?c&~ zyniqNM3$wySBelhiE!Ub#JAZ#H;tdlYaK6}Q~+#q+dK6-RTZppe2EH)3FEQ&!$t?J z{n-L5I=`r*PD`iJdFvCZ2G@a8PBFLrEu=#I79JYf_g~(j=T%m?zF#pX;Ac>c1$=!o zoklMBLcWcWn6UZUPoGrIqXO?KO1Y`QaU2DbJ74L{*X5kXm=s<6zqalvRS719;`xl# zFPB_<#8`!PX0=s6VKU6wA9$ zPcuRN@sE0Rk2x2kaF3<%*B_~ry;G1C@-xmSnvAWyxcG>^^J}L z&U4e95CzGo<1ye$rDp!0w7UMm;qs17d!zA5EapDHlzkYHGI4YKsRPu?b-rc1V+78u zenDU197>ioiMa^n_Xxb;QGQCzYV!tQz`04gt`E(zBp&q2qwDw6?OsdLAnU5IiMT-{@C+ ze`y9F+meV7wBbu`7ph5wJ4(3-n<`oWC}@KXUb4vcX;~LOXM!?9F-c(hGC-ju6Jv@7 z0YbaS>T&1YJuh_>1G}fnoxR)T3aw_NRW{m*AeLzibnJq4FBMlG?Gp&XLbOUxY$a@hOPlblYY)(_Y#W$AEd)UNeayzWX|-{-v`y2X8(0)xril&nQ+ zVSKCJ`|MTMxeylonsL#_yvXq=Af~bhrVj9G>=aEY5z@{YaSkn4YRXBoC?j5H9ksjD65C@qpSBDgFCmp| z`nby9osSeO&gfBxIS1f4>9sCkvDrg$eqLM{j``5ROC~}wVp7|jVo7{>8=#8 z?p_N}@$f8~x|7YdoUNXdq?NBv_{{BeP>&gmuG*@0`kvjt?)r5)Ve{QxiB8?}XRq6{ zxc)G{6WBb=NT6hC(^RkwMF~d=2A!_trgO*!A{*ifP~I+h1gI{F9}UzFEO^*SejQ(~ zp8LyWDA7W!*uI+EB+c*X*GMXV`H|UJLu%a5c@Rz6OPOMP*|PJS>_?zX`i-O?@#<@c zruieKY+dH`C*g;*rPuab#r1K;Gh7%~Gb{Vb9_fN)9<$YblAX7!s4Mr3?W^`XCkmJ& zNw755k9n4!NBl1Oo85imMzqShSir4A8^YY`3q7AZ;ftq>Z~7)ov`&}qkyUL=m;ecE zv}Ka+bU+jPxqcq4D^En!{X)By&xql;Pq8n%uTWBSXp8!0#Lgrj> zzWT`;mI%U_&~v#=*d%u?idIdwNGl&}(}V~CI6qDIA&WbwyzU4FuibLHSp^qFTx+}w zr&h=csJ30gEiUnK;yn?`26Gx04U1FML>~1j=$(h;R1f5^%XzP=0}yjvKDYHAQ_@a7 zY&Gp^$6C&y>T9jIui8is+PhwideI>Bqvt(jJYbt*I?}fH!6TNj90vdBCnThu2M+|4 zsxWZ1G}&+4Gd+a=U5LQrplcV|^7e(~I1s%uwRgv^7nkSZYF8NN5R7*V!M4|YhoUt0 z7ZC=N`hB76LXXYElLMv8IBZFD-QK9qEzT(Ii7~;v#zy^D|Jc;lX)2#-FxB26`8o-_ zn&{_=l0IZFB=uf3r^`GxpJ}Ruhew;wn9M;cgD3CM<4{6dc)7R|{Pj%`4{Utn?xMT- zRc;S)p&LMQsjuDq>bQqr-A?$gI6H@gQULVbP^QSa=4+qvX)2Xp%uCXCQ?hcb2!N_p zyMMEle+Ml{{9aBC0b_3v_DtwDEOSM z1)v(gVmuvP3mYfj^*%_2PEnr1?m@vqfEn*4ij!5#Q4$ht$PwH<(rw^YZFrL-s3;_m z)5slv6fGtSzU}R0(j3WNS@o`@&5l0ZXnE0V<=WV37IfS9ChHJNS9Z2w9pn!mzXZ2-=CtSqbx&xe6?5xyx`LdgV`pEb{#CN8@JIyF#q z#>u#^!J_4nH-1{~(JSX8Ny4uHYUbWS)I{|oy#^6f?Sy}DVHhLx6SyfU0OA#z=JIlY--7ee=Vb6B zL?|T(8JqnOxJ=@=*KzwP7tLt$5RwA$RN&+wF9;fpfb`UA2TX)0Gi*dZMBN>(Pa<&8 z;YqciXO9EW$yjixc5v)=!0cqZtM&s2wKt>ABlE&=mRVPXavk} z=AsCgIR|s!?ezN+nikp{NdaVnNy*P_}$?tU*h!zpp7f8>6supTo zopLf?c}j<)ARgu5p@hL&4$!?4P^Hb}*}iz-+`s3&L(a?gr7SR9*lKe3aW*g?L-X3> zw?6c>gqVPhmbG)eJKe4u zp8kF%-;&!&V#8ZxBlr}4&ETPzMD}Nm5}6lzygg$vBbxUE$>q`fat$qTK+Nc}*corZ z%>A{5Pg*SRgN}k^Z7n3YkGy0gPSDjO0D6CbgZg-ATAc`~bF_+sZGef;UrD8$s>f`ih9lA?SxGdfUTj0=JOyuqxs?gSs zd^l&9(yEVY)=3MM(y#vZtB3m+h#OHM*V%KMPrnd}BYY(&#K4CK((aIu&)S{CzqS1ePvQOmm4Ko61;YMO=CPs)re~px z$|jtsogSZwzsqoy@wPF(uv1Z7dK14#LTwpQmSstf?@6` zQ#rL;lwAWdF>Yuok=4$QZb{B0HtQk3PIN&Z=XVubR?or{PzDZ28KxWpqm1wnFs~dt z+cwr6yZcq5BW-oi&qj^=t6!^*5qUotKs!_;LL*|)#owM|#i{DxKYXWouY7{>alA0A zMFD~hVy5ib`1Qv!h?K(V92M9?LkNstm@vFw>d&$16U{$JCknWO2BY+elbTrf)1W8< z#}>z1i!c0FLnsoPcB{4%-@58lnwR3t35!F++cS2&W5DTUq>&Nw^4~hl(IdmiKzbzv z^|LA;;N3QaTQjit81M$G9yUs}u2TYKV|({=3Yp1Q=nnT~1)(Bz*y(8y z?E3!OrkyCm73}*)(lXJXV|j!Ku1X1kbwR;5-DAPdJZF#yhlVSkVPu0@O1lDON~pbC zcrXGXgWB_-`s0d~Z;Jg`SoAZdYHWGit^(h?+HL2wK6_CKqMWvwM1S1nrU}4RUaOAyhlw=}tE(X}=krow@{D$D}5#zTm>M&b?9bWhju`{LF-Wj3sFK$lY%XpkbSf zY}RvVVHP!>S7rrL6Q`g(3qp~4+#cQ5%(tD!O9Q}}g~lqWM~n5jFx zo3bI=*@<@jp-zpsTgaM9srgmDB|wlt05<_YGn_vz)heOv!aA<0c>~q&;g^H2uE>8; z6p;G;*t+L|ZN8e{?`kACamryQcY^ppMVzP~z%iW0ir&3xX%tDoPhy2&!;ABJG<|uK zPPaL?BBc{Zn!3ezlT1m#dAFRM6UzT90b&~-{Pnw;mL+aD*e}MTV{|l_WiQhEMia|m@qOcR@%DVO)|1l0iaB2< z@5^hxnD0jXhc#&2rf?LummExM&F> zatLIbmcAU8$>Dmy=;f)hXVBw|lw21I{^b>p&aBF6vZN8Y)#qmBn>e!mr#Wv(n~ojn zp$~d7Ff}`=b*bSOZRq(SY8a!`5n~2^vm~ZO0bhX3NUbGO*`ABJbF--=M^)a7WIB7X zBAsRg(HiJWtwsZ8nM6MEF8B%XS2uY`=I6ujDrMqlW-3x3NuPzKIfo%KLj$8&Bt8^% zh&i2olqj(UaYUvEgt`2pPFUlA=Bf2#PZ9$XL9>B`*>NDAQ2K-2a!COyS^|G?)N2_M zLTq&TF}OfY&0Df#MULV$KDK%_-$=Pp6SF^^o$6*k_O-p~ErUgY#G@u@K|;d|2TJ#d z0sQUP?Uf>GM3_RE%AT2uleAV-YC6pZp;t~J&|<5CU;KS}yi|FuEk5u z<95TEe#oFA=CzNYLnyBZb_RSkldm5AMmi}lTLJ6-YQWRzZd~nOyN+a=GvKY=44(w< zg2TK+OS^KH6r-B0b5H(s+(VCWL22y`oz0sQz~54?(<)}W-h~NCQGe&62?hC6$*;hd zpBVM+ezSA>C+e+2dWN{II9L>s1RJ`Z>2UQzP;k0(P%I-w?Ty>{P{9M#1#AA^&ieQ! zZDtY*uH7O`gWV+!-fP>`FOd1Nm*Hq3`Vh{yy9b6XEJP6)}$h2a+7Z0H?m}EElWnf%+OD1CRZe z5H_Id9Pg?M@z^qg<8|g{_%WXcgIM@o(8BdEy$4=cTWqb_dFStNR%pvxx7+C`H&2aZ z*XgKDe*3Vuna$-*mzhSt{aIj*3hclY$b-0K8AR#SGFNjs%y=dKEx^Bg-oMtd4QYmu zFM7nc`)~wkhU?3jDz(2o;=gxz;B`Je2+(ds>QJhW4M|p&-VTY1PQ#=dCR}t z=nN=Q0&q+O(k1dKbjAPmqW|))6nRPhAYyrlHOdSj!J9cVsXw-UjQ~3K^(cA|{y&b@zqROt z2FDLbv|~h8i{{^M*MGH!H~<|BarmYz_x|6u`9Io-6}W*1Blz3Y3=xG#djqG$ zU0U)-X=eemWR*-K1Zt*S@4E0ChwZNd^;L91%RfCW7X}EIFPg{YM894YZB~s)-$<~* zVb>!il$_J_0c86XPWaxP$LADjCdDgJam!!?|2>X?l9PV+rgL6p;ES zO{@AObbGdy`6@lvxf}$}iHJ>?7n3imkUG!0yX3qa>VsPSqVO~}U%*Km%NCC;)Qmfm zYqW@b)OkLHp;Lcg&XxT7g>NKr$dF*@zt%%rn3zBy1W~!VdVt@Io_Ff1u@5HHdmD|L z{qoig^+1Sr(1G_k_FK~D2%Q3p{43>LyKen`-XXuc@Fd`lj(yXiqRrS7$Z)dLZGTt? z|8P<`9qU$tN3*Qy7C#c3>my$C$?UzZw0J!5(8Ex5}Tx22)xVp1%t9EZ>AvozzPmQoRlNvOR{#W5(qJ({WP#hF6EsU zZ~0K@**LA7Jy?Cy}2%3Mi@04Lem@xG3E48d!dz@?GC%N>)GLQA{E<51txzP??kzay`o-9i``o$P`eLuR{6sQG&Ft3>7@ybFkLVWr-xkv3 zjDi%&1`{Ezk9n2jNXJmg5ZgLmxyzhlBYrEQ+P3 zvj6!i_N|8EKzBzGem`VNPu`H$j_IoH-Ay*i=Hhhu3Qozsph#*u`;0%WS{cHGj{BA3 zB1a{)RGu_`6cbYO=})|Ajo}1V@n7=FMe-4#ql~j+kw%kCNbf$5D`q{DI~0eF z+`MEGAGi3QB}IFlPIyPFZf$73zFy9wTcAGaqIT;w{P_ME-ZP1wZspnfhidMU`}MiA z7_rWFoQj!Jesn{nVYfpuw)Rg*r@*aK&@-_`_g=?MXW? zHw;6-p@r*i8 ze<|o|T+dAt`!{>G~hYeF=y0v5Y`hnQDn(u=K(%G?r;sOJF)jfvR z*IkBBOYm5}9xH^LK`Th18_S>Z*x5GkdGe=-hMzCy?Co?-ZdoAc&c_#rc`JtBYt2d@<%4MuO1V6vX|Fu)^`nU2J1+aH$UJVY3X{eXeU46V z#yEPduU^lO&c&}_%_eg4UMo?Cf}11AACIn)P1ZUh;xbaTeH^g3*cmfhYtncKuBtMa z&tDNp;xS56(rGGGEQA2)7VUKWIbVQ7qvFW&<6@DD(dh@=Z$Exgh4h{y%2KJ{4wO&U zYe>~`dUe2zP4=y5WeF759-5s-8?hWT3Mv=qgXiDX?6YQF;<1eb*En`Z=>gXuO<9hr z*V8?ig-%=oNE`g^x!v=;BOceKuLYCE{71>YUtc6b$mC1K2-x;g{6A$KHO);>!{Y@| zB)aEIWW%s{Sn3Ztuh)CQlbd2Ti$PR9?pc?j` zRDS9usOTSR$9A<>0$lo`1${l##>`xAwYyFr(3ID?>xLET3_v_I#Sg6FcY)bhw z?YV9$CwoUt4)I$BzeOt3@Z3w_ZLi|7ZTFv>kaXCknR0Cw`{JVNDJkH~d-74AJbk95Z8ndH^$4aYpEL?7b&q};aebKwj z=F0_Tao*{op$#&cVfvTs_RWK&g}m)>?AIF`W>q(7IwlP9hR>=p8pINZ@zzX2_Hw|H z7s<)YM&?;6!3XAIk95viedlPlH2uW3R4wnL0*zKt!pC5i5hGgfTr=iv#lUhY#l8=M zAA)zS1=`?H3)~#cX|oW{gx!z-4|{JJ7G>M^@6s)eARr(}BOyq`04hic(%mTC-3^i= zAtBwJ(lNAvbmt7+-TlAD`}TgG_g(i|pVp_ftuJny3d}jf73Xyv`)@yzg-@0L-h6?> zM1J4dzv5v~;de$p)l6kbRz}>MrD(#H+c{ccyka6umm?YL!XVD9g}5evJt6Q6SI+e? zZXerL8Aw*(@RGu6(;MHcI5w&Sf4eeWEeE&{Jd9!0=7t~nZz?iRiOEtGKmE!?#`InW zg?=4w;^Sno)gN6g7z7o{l-66eJZpC6@X(1?%hFSzHBHOl+st>L+Pr3UydH2I|)#F@SPrnAuaQwoy= zVTE4iD-nsytgzLojVm?kGdMrE)CQbKBqsVkUt(z`C}0B^OSFGzZIfoe#r1u=NitJ@ zh#%B#dUtn?^OcC~C!0n#?kh8Sxze2kTL{6d5`%8Mo6}CXf$P`l>bK^LPYvS6E#+&u z-+JFzUYj1_W03HRb!#@+l>T_xiH2-4S1d`x)GhZgnAZ9(#w$ULjN2-AzTR#)z*ZEY z-I~RwMC}OE@nGUx5?7%dk$OV=Ho9Dq%y1eV1PxkX0%W2(hur5wL@V)sx(#(_3niSh z2EF;?0(c&trE`@>{0k@&Ugm?2(pt-BQKouww%V|~OPSxsj`-yGO8 z|M8K;&#y?YDNvd{1z|mwoDU00?4O?ViK1Phg1-twZmbVkxaf5X8?1!a1|?RtDuSqYW!>zq7r5B(eqKJ zz_r$>-eEEr2zln2O%5Sg)cPpqE;qkQ6}02>18IN4Pj@u~|7|Pvyyn5-1v&n{ba5`& z^TWxU)Nv;zGo6h!b;J{Xk^QwV>rYfNsH!hoWW*j6|Lg%XaiJiSR8xNErBFl=o7rrw zbs8cF6`R~ftKP1wjTvP%cmb1KwM^&7qHdjy=yu|DY1xv{gRg(9{d2j!4HHO3m?rV9 zkw)Kif-}?2%|Yu^WDMeOFBfx1n3&HTk$ZQ>e+0(`BkJVt=F6{XGHTZ9XDP?O_@vV- z0Pt{e!T#VC`sb8u`jX@faMn;%#>&BQ2_0w;mQkLJNODRn}5!nmKG{a(Fjs= z<(+nhmK)v-E=&sX?eqjHSa*NFdVlsljgS6}H?vu>Wrxhk|I0Zqo0EVYQ>w6eYOMa? zIbrrWHNhQEkGyln36d{o}|a{aqA*d23>WBtkH^8~HMI`oEviM2mVBp!pwS@?PP z7o1zzuCYm(ENd+0w#Mn|T$9W@#X=N4o3=nkb*F(9G8lW!*4sNpf0rkGiGATx#e~NQ z)dLXZ41Dn(QBjG!vmrv=J?L=93$N(uUs`C`TyXXwabh>q|25}L%4J4pyxU{-gHx;x zs8bdT+WQFWQ2|9@(aO??^W-K8GPwe+u0n;umfO@&q4hO3wKuc#E%rSnO`1`Q3Ll9v zsE=>i;pN19@zgFEOXtY13Yvf6bvH|{U*9$v4 z&g*NhxdZiuaDdCtlkvvPPiEiqUKujrRF0H_$zbt4};t_){ zEi!*eO>`gzRU-TjzpvDLPRDW)z>@)XK##_{K)4Qk$L%t0!l#R-bxt@h*a0+(&lhW> zN_zfOMN*v+w%wpBqc|&WdJVpq2=kB1$??(qja(gliK@Wk_MT@GXL`p06-`Q@WW`#d zB9*H6T>+x$MXE@+Wpt`1Q~pmidFoy;@>s#6+3~oD=wip#MifpIOXo<(r30q1SvM^H z-RXL=J6>yePmohKQmcIt^ea5%T8`6bjkc4+w7>fmYt9=04$Otkr|E)iOgoUYv~k3e zX#7NLOs9OeCkiA>G?1>MDFq(C>yrLfHIEZM2k$32nE0gHgUk?ELHDDb4`bbO9-oH* zD;Cg?&MU+4lI&+Ip zww6+D*zu*$lmp@PXPQ^e!Q*@ELvFu;77bm6M!}2P#=U%zn$<+ggl_i;WPEA@%<2E;frDV z8V{`+gE&Q*ziC~vYhe0LOy%t#h0GJl{n8p7F=3&a(t;Yvx*zSt#2bBgXW zz2$_1%>i%cQBnPeXEe{h7!M8ZF_?ahD!H~_e|XM{pceXI+%nXag1izOD+B62gM%ko zYSELcqYRF?PsLardi|=Uz=SCAgmVhabZCb=>)t+BiV8>@h|qo_0?oRag3Sq5 z(T=Fvz9(l*%b((&%i`}x9wIv;jNue*7Bp6ujGc14XM|j4vwmLcKaysDm@Ete>Ix4rneUPp;Uom+^NXUuDZi z5~WpcNH^J+z}}7CgYH_2M^Z?<4vuob$M{8pXX`~Wr_2B*=lnQ8YfB+GfYmN+D8qEPUumF9)HhQ5iH-AIntH-@ly_ar=h&0xQt(v z7;MB&=9_$5uL3APx}@L$G(rZ9Mp%C;_FlfHX2A8rCst?fg+}G~k3*Voy21!oFOhPZ zC)e`&JNK~&Pwp=G@-@+;9G9F^X*56Py+q>d97LV=gg+7UOY=&z8f=q2SZo|>LvWUK z@Osl2tdIH^kAPCHxN-ZDqDNMb2Oa%ou%7+-=@i7907M(lVwfES91-$|GkIIQaC$WE z7k1%bFZNUk42TO-mUcx*W<-Uyz!zo=;hqnS9#NUkXZa zo|JjQz;OV@{|!9M>_d6UVZ6i959WcX;nZs^a;A%7p@a-Zod0>>*hm6b=^W!GYT@jb zBH6qGG$VDY&WP@JhdQWL9^Y#T9Ci$TO&=K7^LZ@4jtSpst6XEAFHAN*BOjOV!`*=E zpRaiHlmlxQUHDuLKgzDkV?u{w-ZrOjBIl7c=B7%{`#W)kkIq8BFB5|G6ywE;y6f;D zuPIo&jByUY3l&FVO*x-aYDLV!m$BFs8fxLFVcGWal%h8E`zZ=9`jjo4=}naieVqb; zwAzN$mrV-->pF+4ZeU+BA;&ydxz9e{8#?Blr`=)dc(Y6Qm2jw>GT z9;xnH?)G$_rMqfg91vaJt_b?u3)!rFI^fA(f$pQPxIsx*+UpX0o`IH}w<(Tj*oUB6 zI9eOM1_9&2m|x6aT9KWTAeTBG3In^*yqcuEzpL0#S1OSqH+;4Rd0d5E_(l@kd5&u| z>*J5Rmd1!}Br#K^+JGS1`;KSATmY8<3XFeOY2m=uztwHL&la{$WVlObYsAz2p&{E# zNeJD2Env~f&?^DgS)Sbn-%;#@OD(fZdoX$FltGm_G!!GxZg;9?9@#DNbr6{fIs1EQmfE2=a43-Db{2KoCh<-CN|i@Y801E)ZsW z%boCeZWmc2m1;l8ViA%E0Eooa6W>$4(*(G{ZicsHBpGyV@}d;mr2e?w-+DDWTJGtd zts^f#N@u+tlzr(+UH~!b-3e7Tr`1~k5X&_o11voqb_4zL!~l;@UXfPdA%%=Y6OI3q z98LFo2Qr9`Rph~ZJ@eTxeYjhUjnzk%*cnBWAw)~yRxX@7_}%yTb`-0rSFsrg2Tolu;r+L9yg_`o=F_T_Lw@iiV7q6v9U}oN*`Y{}V0)!7!l? zZwYu@M!j|>da=8q55n#j(q9HmBYI|*0VHE@0?8D`1_}rJFQEe_LL?qJnxCS$VlwD4 zxSU9LD?Mn)`t=vGpnsSo=v%7vQdHs6i#m_1%1)}o9I{TXcVEDb*0wfx?wZ1p+_~f} z4_7B^84OJUM04l1Uqt(@7f&sK!k1&WS2p=1uWLBKk-Hw zjr#~s3n26ko5T7B`l1Gpz^Ig(^g-N5ltxM|$F-F*kY5)75!>WAXSIboCpcRx@un4c zIxj6nC5b}DnmM-FsoBG)gtL7HR9VGY2-6d~BT3(19ec6%oIl9uwoSN_mZEOXo%$PE zcwe;!pnragSWh<{Y1>tqR-Awsq-|nI_?_1^G?WlWqcrt}`Qz(CFtJk3F+rqnzeByN0P+ z_p*Q_Qrxv(vZ1eq!%lpPI29Hpd`tOsT(AMj4 zBI?Qu%i)DR5cOa;zWo)Y@ye3Q_0pOw?PfT7Wvw}JWyFv^z#ieA<$P;0HFMSgD?QWJ z5X{m2Y7TR`S+b>pBAv3%!~yz(t_`{W6eRmCNDcbTeh8eCWmF;d(#S;%$L$dsm4z#M zkk_u8O1;Mu=G-7YoEvksee`*E7MpkW^QtpdA8Y0jZOZI$W$UBvge5ylu`Y^Tp&AVh z6i7Tn!BG?+{BtdhizKiDhHwEM<6z~w>YdC|{l(r!@qh0@nFs{~nUN~sD$p)_Efd^c zv-qo37zAoQ2kZGG28~W15t#O6A0e#_ywZOUWPkFEL2UFSZtrjr%%+OpJDN|G`>|33 zY*q;Ka1jKK8F#s-sm!?mi13Rx^Bef2mrDBj_MjgjPFl}DZ@JkNP#xS=;E~-{%GJo% zWz%VT(j2tDo-A?YXl(gDp3xi{NkDAbc9LorsUM}rNcW*BT zm+-n8a$T^wa*>Sg>VRdOYcl8Bw8`nJjdeBk`ch_ji)%k-xU1PC2%^aDJt+iAP+~*(uVT>%ty8GjeEahMNiZ4B0-apVoPwQ zxM#teFD_2 z{Wg}E1nKQzEzrs8!&QOo)03~rO~rhY??nQZg%v3j0FCUKPck;Ljh{ zCkAju#xwtJtE*;!FDPD5A!>o3VwG+S;(dRW<*hbJ&0hQ$7x4xT29UsQhs_$lc`_QJ z?vrP?2$Kq@#E-ZYku6q+@Pn*Ru9k~31Ew+F0oY(}{6MlxQ7Mdj5i~>?5@Ud-P;8<) zb&2@(|MbyGF^=ov6wl}Ymhd-7!o~soe4XX61GnuWFKyY{X;6bq!B?wOAy&WoYt zTmGuXHs+>m0qJ!arRsO`Hs!?8DTC_hO)N;|Sl&JR&9UEC*s^6(cR_rXi|~Ff^yuiU z>UDZvMCkVf+x#K_kSWjz06bXSG)esDU;dk9`4$fRFWU_A)R^+WfiVC7H~%kO#rOZy zA6P);?(tf`1EAcw-bnKno1xC1WiD$Ht1#%w1Vrxv1t}_jpoafChJet*2jDt*7|rs= zZ)d9PW?cF^udNcx;pg;!5QzW!YTvxKu-20#g`f+&7Bl*85l(p}m3D)J@Zg)||C}6u zDp~+Qb(jJJXI{>?dV43h0daZKt`IzbtA&QQz?C9zVsdC`h~Fy}`!TDA4D77u|6xAb zc+fzV6s%U+0S+yJRPj^n=le&Mws$$6vce} z0CSjU4cULhoZzC9O?hkG@+6Kaj@fb|O~@KAMZi0nbi6>^S|ZA7ZO2!@7sw%u_32J2 z#D(fAevJazmEpGWxs_0plslFE^_a!>97gaoS?J?o=y=~b`X$4w;8L|2FO{|4e_h#7 zX2^%+GnVL7MNSrLyhjJ2@x`~VGLGfTwfb_Ih)^zCfb_I{x??h=3@p}qH|UYy{Q^0>BrtL2vO@uQCUknbF@y*=Pbm_%ZYFC zJ>IsmJ(pzxem@6449Wd{wu`vH_&*A>8tx2$432^B)k5M`a8aRla24Rx zc4k5gNJR`bx!{`|smFQ2-k|Kapcfg^O$4tSs!bUrB6qF!5zMD7za$_UOT}ehK%(^1 z5C)Pszfl}D6{-{%t<7oU++VKX%vQT%rU-imz5LYoZl>x}jv9xdhNCUC_Y8U*$6UR; zK_r-09s5d}F7Nu{;NgAa#cl?G@{Dvy;PgiM^M4$Qk2C1@fE4Jwvj%#OBFw6HeRrR7 zH_1^A_O2f}upIJE6ey>BGpCPU{~OQ&_L%7+Iy$=>-y$oG`rdrTzZ)uWch{Ai(MGT( zMW`=BLSI%a{muvYmI>o;LYkKVxWwdO(bJBV1T$RtW>?YeV8MBB;#3ViAQXIsNnD`4 zp>v7{NuxY$t~I`SZ#GiLYCL$E*mK_caF6;_&?ENzDQ{;fMik@Q=zjAJV5tyk7-TLQwG$*5k9gXDb<eCHnn8%`D z2+T^zRj3+Mb1+YHM>8k_Oe{d(c-U^;H_YW!okCm%HaOAc4lOdh)bCH=yjd3I#Bj~ecNJpM!- z9(o~3Ds?*&Oh_w5=&sBs?6}Udx8%OT0(nj8oe-kUFAShP4)=pyp6;8694)EptIm^N zsW;JCzQA5w%C?bFz52^(9LSnAlt3W<6^fU4`ipfxSAB}Q`-9t?n@OckPcN3k=R~(J z*{WK>7mM&M+^wI@(F1s_r#MK%yU4CX^d3X-Tztf1g!6*Sgy5 z9!Ms1aY>7_4DgHGn^QPwK`i#LXMgBPq?Ss!0DAu=b56sxugnzpk|vB(b6K_Ur98Ex zy*5B*d+5s@mlZTA*FV0w^9R8x)QTGRrLjeIDzQ7}%8<&ZuI`9W1uvHsn70gG8U^qC->3VkkR>u zwYiIazVG%T9pElcC%z5ti_-MG&z7|iX~_MJv+(>I&T^+4jZ5AAWyx^HMNls;*`Mur zJy&CbDY=$HSD$>+ax@7Rc57}A+5%F}DchnJB-4#yF(0%_tQ5~3y=4?zDYuj^fXATm zTtjE6R2Fo{gK6=;aQQDlI^dqQwZDCbD32Rpq4M7EY4ASj0zOnA2{dASzfZzxksi|~ z$Mc~2AfVMwzhlY0wxE@9^D|GM2IsDHv5UdK@tdwN93#7x2v&dP zQ@YoNd9c_leR&k?0kk&gZy(I33f~``U<4@_O$~$FM16n6vn2J%5&L5W9%3MGw%TyOWsh@u#i3;U*VXQfrk z)Co%BV0&&jze3V30vxBC{y4&4@=|flb7j*ch1@P;d_sj9oim~?x26E&Pl4&lq)B`C zt%DaSQT5xL=CUY01ZQ9rY#?OO^QJ&?ih|k#YjaLo#WsC!Ah|YQX$FIuVLbo-5lEEf znRut1bo}QK0+5$r63-_T5PDd|c2cZJ2-2ZL^<&fy{|_LmPAYX;!)8k15LE`D&zauA zt%@4J_z(KFnM$K)6@oFW!5*k!rN zd`Os7&;rYwr#rW1fUNgYO`RR!NjR)-{^m(M-L8kwkaLU8aw<=slwmi3QI5wG?ce76 z;4Rd=HB=022Qq9N>)HTu5$hL-goaPxo$zcbTWtwJ2`Fb3Jpem_AbJE!m4{qvTDhcz zwC|L8fK8zPtVk;Zi-=hXygfDM%d!6%3WzzN=8)KB-IJ1b5*uuBmV!BF%m{>Qz zedTiB>vB);qTH6v$Z0GiKwNB7Fjf~=H&AW5m;g*7de6R(sP^11Az&xSov0Ux)B1=O zTbPWL7KQB71f52^sig!G!2#FK=#$P38lEyH#>=-lp~q5$^&8L7d=AoEw9%K*094B+ zeCXZcJl_>3;eZD6k|YEB6cg7)OW6h2`agLnu)T!OgN;Y-)_fo{_H9$XDWt^{`<9&7 z25bw6&rr)qzEC=`*=RMpO}Ke4wIdgN+HPzKy0}%xvVmbH3@U}i{txAL+aKk@@{Aot zl9scMUz&g*v26TV504od5C|l2G`89mQwXbo$J>Ei<0dn zUi%)%*|(&+#P02aZDn!~zA80am{)o4Q)-TF%dI-Z3v_d}Xqh43rB75WO9bupT!s<_ zAVyn7_-N5^AWLVZLLJCR^AJ_hK45%!ZoL(%45T;XA1XDD8&650=jz)+Pytj-ENq=5 zHcOW^-|>z^uWCMdpwOx#=|tR>;U{&O-+ma5Hl)+kk$rMqMgI%Ac=z)or>%{_1^VwJ z*p4GnLPwQAFFWf%&%LH+Mf}CAG-cg>>F2aQ>6!ean3T|augl>!@y6H%0JmV`^n66Y zJ=@m-U#fgklag}}Fe=3_IlY|{%a3iq`^XAYgUGu!rS~cBd=p*G0XIv#^_VKcWvS5( zyEO)DOW=9$_ldXN^Cv<#psN&v?bD}RO4l04Cv0^698T?oy=1uT?R{00E)6OlcZcV1 zS{BF7>o+U@ASD}taJSc~rlBlizVsE~5ENWos^@i~i02ne&1m8bBq05-01*+)CT#K+^GMZd+ zA-7-p4>RSqRk6y28VhEht_ziGGvYph-lZ`%R_l9P^zP3zrZq_jOc`At%r0C-8Be)g z>!44gW1*2S1`S+CXck+Ld}43X8=oG70U<3#(Z*$lkyoZg<7;aNbj;IJ$rj~?O(+9% zeC#!Ms6nYaT8~+;)Q|P_j>gnb!)@fY03JjE2gZY}qX~MA9{r>fb2Bp>s=`DT_bC6? zF)a=eCl`H!rG|!93dD@%%S_3pwvQ>UHX*DgP|tT_@L2E15#@Bha_rlBYK?_(5ExJ;PR?OzDn;%8#*+P<{P0&QE=l>jqfz{Ho9$I}1wxG}|4`*37>v2~Z7po(+v#if z+9iJOeS`?I$*kN6035C`-r+7(sVY@W-60d80Xm_C)ut2kKbVy7bA#$$kkBm-u2Hl7 z7*I`T_iTq>fO@4%q6fSIx0DIQ4<{Q#OoE|~?|>;JaXIU}-0s6Tn-g!f5Wf&>C2=`E zK2mhK&Q;)J(qi|vnRpIi$vam;zlU}oP)ZNb%OvU#;O&*adD_3y`s<eSFgB`NSLOi{KItDGG)FQ15dz8Z9y# z&o5#CKjYG_oUYwZZ-qB1N^;M+k3i7lK`*_#Cp*xrH)Jn_vZBz1DP6N=zI*6v1rLYk zV*_<2XI|IEem39@bZ&YZSCUbwDpi%!9y*gEUjDv1D$m$?m$Ilt_Y1 z2ddM?`Q_@?uz^R6P>K|y%wZvKz13GoQEjH7>&KXMKTuS(wgr%*^1{;ZXb3&C1KSYZmZ#6zc%wee(6Rmn| zxw%2aY&!U>AogAnl;_oP(oF)}e`obXe)v4P#%P%|KA!LUsSP@zs+;BE3i_5It83gJ znRx2J3P4k*5iYH}V4!KyINT(kjY1Psv_?vy_6 z8ft8xq7|GBY~}SEnjyFysyKmn(gint5x!@@JNs>n*k5dvn{%lpcvB)#ec98*3?E*0 zL=#;11biMO&fr6G)4_W&G!95xOaRZ{c)HUoze^va3^;?maLKGa?cRMvGz8O&1)esn z3dA=LsVU#LR~|WKf+Go=8?L20y;lQ)7Rc$t`-L0HThvZpH0zh$&GZ@R<_Es`-Uy9I zda7u0jFQVy#c+YSWul%94SNO^USlexCwDlpobHd!lxl-^ZHDVVd5hupE^5y;I$Cz` z{}xuHJd}JIh;1fnJrBndALul|c(d|rxRD&pGZ!%cPX=o-|IbLSd+~XYa zuz$<;NEK?lly*`Ba&n6|OU-!$^Jo9i-u7>y>TH%FGNq_ast9$YFk?kgqi?g9OPRl| z(B`1@m3EB!IZWzPln+dEuarr376$Ghdhr{EfXN0pQWf(C%0KmUprXaLbVsJ?#RX2D z!Ik2Zn1=>?Exq(Lz6H3|s_REv;5tmKr^2HpOl8GiDscUuarK@mr`y=()nS>084o4Y zHnV*P9e*53+?l*NNi2CZ(|keM_kORsRqk z<+Hi~+O3p^i?}1`r-K(Wu#;?NCzW zB76^BM${KA94MWy+bEki{R}~Oo1>UT=$Egy#D~@4-m}H^FT01B7qq(s&&;nis;sg! zIm(c}w8*d^-P}R9nfxwab?2oaVl|u@zqA>$150iZ@4uo8Ty@jicT}X@$JM(U8zrLa zchjy}R%N`=zqVi=s-xJQZ=M2fv2_g;(?b(FY%D$c^?4nmWs`qu@rSy2=?`Y<&~Dd} zK)){rIMZD|(8v)9ml!+@y?m>=`%c{xR@7m?j2$!Z`(zI3W8PU1YO$Neqkc_PDdFuo z;LD)jyw`Wti#FQ>!?0J1tSNbbBpd>f0n3!vGwcMfy%lvtRC~Q}cR4ZmBq|j6?y4}- zpTT;5BEe1>U8jN9z=ZMYUDQ20Lb%0W9H3EMvFpgBF7O6qd_?ikw_i1N5xHS~hv7?)Qk$5vx0O_3x5AGT+DoC^;R0Q?{B zLzh)`yG^GWF8yvdt)Cb*gf;h&`-cix7)#vllt+T^kzmF9I5axi@GMX|>P1na zuY>v?dmL6g09s;3XJDkBlFP*QkK_B3`FfMxeEmsoe_%75E7m2|t2RB$4k$8qt=(g> zp9)h~U=0V;Px%{3#^4&@dng}D&rsMd1j&v*)G9M8=3(y@*9QaV>Z572Jf94jY|EuG zjN?huH@T3nU16i(d(UF8*Zl1J2mp^b93S|INvGlaFFxi2)l_avQvNn+r77!a2JMGx zJ#04pM;bMj*Dqz3DuDt5(`?%uWBVH1{A0GHe&O*(@78!t1$gUSUwR@ixU}G zt;s^y?rju(cG`aW+@J0XSWDOEJpc^WcDpvb=2Fgj$ptV|R!X%D*^`(C1sGrlu|Uvv7J=&-+8}uMZ*8e)Lm_7NVak%7t{K&Wk{Ur6jekn!@38WfJt}SHjm= z5x|dZdy!??L(x8a3Ka3w8(eoDhxQICz7)LuG>;5$Z|M!{A91Fzv~E;g=0tQPsSTGG zeaw9%bJ@NVD1;hGCic)Q9v@aW^{7OIoay0T)&OW&LRZL9D$4=LbG_*o<;vOKVw;_Q zo!1?Y*S63b5)yC`($SQ^C$GOK5yxp()8F2>Bz@7f!+uP|9Oicv?vUk~^6+ey^ zzS>!Hd%gjYd)IU2Ot}9UXspXGBthO$+;hr^kpWJYcDsWcH#tK=*?&rYJV410z&j9r z;~nTKf8iY#7D1{2-U00UN!h;uLz*RS1GLuRXoxEiXKPF)r`=~$^~g^M9QeKO{fs&e z_vRW=+opx=&%YC0;s!n<Ldx)hZ9UM>L%|jvJ-(x^+=%GQl$&Ddr$UDwCwR zztP`zSWZD@(3AIO(#Za@dP3k_s8RCR6$6`Be-x+MXlsaCDgEWTLXO>AGr-$%3(xR0 zU>WpX@juLlAto9%aFFH-j{urRTTu`i=j)G`ErtkLOUgev{ zpu9he9>So)(Tbv^a~)t4Qyo+0s6f0bwpna9vI=-VB`j|;rM>*o<>U65CN$9 z+fdJHh1?tP-@FD(7D15ay(_Pf-FXuXj@`I1W z!XjqvXaWs6;q{C{*Yi|FHs@~*Kbh5wzmSBMM&u17NdQUDn)M*t?ZYM*=_!2H?Gtn$ z-~m0^7%$DftG(R@Nu7cU)knAQrt*e|eD%ntijItT+9sFM9!)-5!0sQo) zpQ*H2b4@+6N#cN{Jack@R6gi*pTpL#Q3bdrbLi^so7%Vhhn{l=l=LB#X^ZX$LhkWXhB_Z*zp-l5g*;`?1;Ps$zqXOa zTYq^U_N>#VS+`tuPTN|3T7=ZQt72;-lPZ=1#ye_sFmGqf@x_b@2EcBhoCC%sMpm+c zXP&4~d$`y5C^ZYyr(7tFlp!{uKTj6%ouumA4^q)^aNoa<*%cE7@=w&GqJpmepnexA zU^`uBbb;*_7U5=H^jPZ#E-RmfwB>9vx%BOl7mmKVOLyej^O~T>*MJ@E2m>t}x{pjl zm@t8k)_pF$ESi=8Vmr&@6@2(o`V>J@r_sy5^|c}Yo|mteSd0zm;S91<*L=GoOYdce-9hk1D)vXUfjUc7qrIoqhdVukCNjJ zH*g_qf~qSd9r`duK)28zmJtSHOz$@S%3AO|L05m zzw(PVb-Ow?Zm?ZJxjPvG(J?EPl{Fn>bcGUy;Xi+eTX?PUALG@39Y!K=U_}6lc3kvQ z-PV0YHbBGrp#n_rH>>t9zq{1Ou=n^J2x_<4lsqpl69)JBIc$wy@e){;{_ETNEjRjU z^KgHszx_<3+Juls9P9V&48ZuKq6q?lb}o$t5_nB9QUo1CZ|7=qoflmN#N@p1f+D!Q z+o;W^(52Pl$!MaG4xkI^vd{v5o ztDo9I=V48)l>V5d$0;SO<&PW%H~KeYV)bt>l1pPE461mKB#zCfz7I4lS!^d81Qd8@ zx?P16CKvn7FrUYGi?+FW0^m~yrrJd@E}@dLwfkkF4t)nNG+yL?koE>Vtd!d`^-pPK zkB>OhV%|fy2wV=K@DmopV*G#85^p0bj(4|z?3}JATaVswEV^GKg1RW^0Z;@8=t&&3 z++YLwPblO0?xM1dp%4_3S8KJ9>kM%X20-ieMfO;}#X3|TCx*sJvp9steTqmYZUW~6eFMV^4GEk0QwB!|y&@97c(}PaM*REb+Jz3Ske1BJ^Eb3>|>O z=#f5DN-B~+RAM)ymrE3>s!6$OT;_2*n^1M39WCOrb%3L6y^fU_*-uqPSj3v#a2y=6 z(|HJ#KV%t_>-p#Ap$lBY!4k87XbgXkgJ;;_H8=xbp+HrJX<+QcQ(l)4sW_JRd2(qP zzz%OTr(ZSSIjS^X)D~bEW`DTjSkBZ$WZH)Z0F&hvujTGs_{_i9=&x6p94R!oU$A;A z=HTyvY`&K0_3# zc$R`S1AS%ebv-~9=&-h}{Ny5nXYq^1M^mhWhe)Uaj~A@SC9 zg~)83D`t*lN@(S$ekRxT)}CFd!;aW3!nHVtWiy}K1^4q&Aae;Lltv^dy%?;}+|T#2 z@Upr`4_Y7I@6A@nu6KnJ=DHj$CzUc(W0jz|r6YMfw*icPW>fXVp0S(Wr=otB)qf)y z-Yvo>(Tm$Il-!Gz1crU-$^Qo-$qrfC5$DF>*rF%u+AHHw zquBeH>X-CWeV00O)y4wI0Aq~f8jiIE%8(n&$uSvOv@4MUW?gO^g#Sfk9B&Xi8uo;4 zsSLeByc^W5iv`AVr)A3yXgQ56W%V#%+E?6k>jDCzy(PXZtXuXCKrtua$u@J-7e~Vk z=(HoS$@$we_sQB>0l^{CH;$T^x!XY*H$a6hxh-!M--v4Tu z!fgWrdB~*@b_PB;g*LX6zE_YRpD6Wn#M*I|#{fHqdsCE^omN(ffYZsr+}Lp=@5(2y zcCo=~x&X2e|{Ax8yw~lPupCoCigP9PE^krSd{mZk{su9a;VKkVHKeCWb3E>MpVS5aTHHVeTm zH{3yy4rjM7P_2C&@sy{nFwFmr1@9e~cjPa0QCv)7<^dED0Gs1A`CL!Fl^5hctk2yE^zw66brC7%#=YgwTu3nwPZX%H*+{!^aX(8#WV$ma2Q>x zaZJk8y9P!p6=@isOs+78SHMIeAFv?zp!-J{nulRc?HCc0mh)nU^fI>QX|!XX#+yE9 zGeb_}0HSP*h`U8UVU8dm%(uBwt*A{N#S7O)FTIgYl}?{;>NnuwT^x9(82<#7=df9t zMIa`2-ySZ(X$(pMiqfRgn(m2rB;6O_1M!g!@}K2idu9qqw&s_c=yrR~l^nZFUsRb? zlR~R(e2v!iqDH8YZ*>6$^IN!{W}J>WN0!d(f)B0r1y;>~RTY7BxG1a%1Q@^0wke_K zPuk24oTn;s@E(Gxf}b{=pHF+2vF=?tZ#>8-lm5kpB-#uubM7ZK zIGVih3+oL=;{pQqWFU{08>a*4hiXpCf6Cz^E-)3Hj@?5I=ih7yL23w~Kgl=1(Fw^r z`x^}Tq^yH3Uu^TtE&1W6%%I#Uhf3mc+}7+4~zD6D^ zrY+u~{7fj(mT9SOE!VwU-)cSfS4FB*mT&nowGSrD(swaZvIkRu^MF;8;M$V?ngUid=zSd-t zU;hvy4}!S>9~0(_W7uBDk`A%*L>aO5TE?L%RH%P>+e{P_*wB1R1B!n8Hz9I#`&Qa? zznvC8y;MJibQDEST7Q$u@!XnG?v<^e>nsbm+vHJb@Nesg*X7f|$-^0j%3bd?}MvH++p)xR>Sd&GSP|zc08X8=?)z#hgMHF&;AOaC5fKEt2_8L=3#&D zYG=Fwi9ue~d42e{mUg7ffO>@JzUf6))$I*wQOF@5S8oV$9q3u^LbLt1+@rf1e^6~* z>z(GSSIYmKRNyfhu=l0ln8SWM5vrHYc(pY|7}X1#oEKVWw-)NJiuDtxk(d|A0h%?p z+AR5vbDnAIcDMtxn7lXMrOpnGv=|cCvOd1Ae)E54I5G5J1V9HiMJJ{F!^)u#X{(AOafJtFuTW#`WCxLuv~Ik{XezQ9u`~Ia__h!2?!+0%=V!e$z3DC88VK7}~b<0*B&pGeCaJ2vf>XJX6 zl4Bviiz+WIhO>{q5~FHW_&wLZkFVsPsifv1Iw5{NPatNSaw=+<)5-BziQju~+=Qj` zTO+bIcVmz>0w_rujd)>_3QINlFE2ZAWMorK19trQeCs9k`Bb^Na_&+Z$g(-f<7yk~!T(uP>XI*6kMlp)R6 zTuCtl>w@wHJ}pugmGVskLoX21m~TD>I5$)bl3n~C>fSOcuBBTS#@#(Ykl?}H9TEr* zAwX~s4#A~yOK^7$!Cf17w*;5QHE3{$yVyJXocEryzhB?4J4UBR4Tm}^<8A`JCYloxIRtE57k?PPWx-w$L2#; z%2>~##f=WGDU9!L?b-)DYfs{b)JtD)wZ!=r7!?TFNpu3b73q7Kg06bELH33d03MIJ zLbIrvcDU0PF&5FVE3*sG1r+!P1oW$T z4CG(aK9#>V0DZ%B<9f`J*;3cjsfn)mfFH(j?e+FdLOC6oVRzw8zabWAVOVt^*e)bV zD;YF%41WCnaYa!+n|9!7+7TTyM(LTM=YRr#z_~{tci=czDBT=w%J?A!A}{YqypDhz z4fXtjz(6;VL2?~}orNo>|AND?xl2vVqqcXV+PL3&l$0al_C>~PeBP;^PMJN$XG}2w ziKJw{?7T0pTuO;h-;Vz<>()iRl6*C6uqy@M`oHU@g&q9akrT) z|K`Qx85#b9|GnO*Yj@NM0&31R~oA^p;#I@vlRBNU_0CHzERV) z+}_AL@!6wRlZki>4(ACz-0+_~J3uRM{5}XHCFYbxRZwGT!TfHnD7HnEVe|A^^&{!r z!V1JFQfk2HGa+4^VS3Rv$EJeGI?uf->eXJ_qE)NxCf%Dl8lr)ezY*7u#x0E{?{JW3 zL93i8j3|C>u&oFFQG#>qk*!J^AlT(EE$4OLh#iXMce^TrrB{6fGt<7TOHfX%{%~E~ zJZ#V`*PIyp>gKEuzq3z}XrjHjA^F+toq$=3mOP%3xp#$r9jpPj9#a1kF?o_s25V)C z@Tb*96WOZC_0XL**-t&XHgnoYV!ZqnduTsK8EEuP4Yed~scIksed9$;t4R?_F7jD^ zp-4N(S+vp?(H{H7oZx}E(3k_A5A6+5z4Rk0@zPw@g|N5VEo9f5fcWG1&F&0Fe_^XZ zKfGZZ0@UXDcJ8cD5xcc7RzsUgBQp3Drat!;^|$(IqVo`$QXJ7AR~-Ic4hR+W^9*w% z47hdSRQNaxdsVmCcHOK5#Px|W8?-m)FXe|??;=emkGp>BNLaUe(Lm!+053lSWMz7! z#N>h&4f+nl22Ct_x10jv8`eO74|L+;2D!vkna6SAw2{TU`To~1p^s4}LH@@Cqr47? z^4k|amQ@s%M|K}Duk%bfYZf{dzYo2Gz9=K*_6lt-oUga>$zez5FhN4c!O#D35xz)? zXAl&;a6z0r2R~i>KC$ISKMs7=pRgs@<^bc9(+I3G&zG9$l&{cWb*au|DRSXfIU}GI z+>isj&_2XC)vH`uz&-LX6aU(SW({^t{bCE$MRjn+Fdo;}Xfpf=oz2<2r-`Dks%YL>hz=KD`)}GoSz>@6r)?nb0#5XztGW?B zi4AabSS*;+miwaf?Y<^9n_Phs&;&I57DU1|#9{pr0}1S+6?|;gAYy=E(ytA(vQbB9 zcJwYdDZdcz8N?n6p_+zQcoav7A9OxdunSJ?7NZ>nx>3Arx`@GR>XJyhEE~xIMpBzR zFy8q#Q-v1=_ZsI0%**S^x_EZ;4u)Fn`6Z4GhPMh_{Jgic>9OiU<6F`RP^Y?`dF_*; znB@08em|s=&<@p?V^j4Lo!!mrds)^f9ld^m^I7G=^=J9w1r+>`tdaT8Asr85NtRrut7fYT zynxWhUBx=Y;DyKHh6pm8T()|1c^@9J$Ym0X{^d=;jnK%Z;j(R(`t>c9QUFG<#XEBq zNdt^Bx$6{TfGfmny6Aj_pI?fRD6f?~Ox0OHdeMa^P>p=}QO)xD3h^CVO)$C0!sLs4 zv0nK$XF}f>_3cx+HiT+X2-N4Ub9Cb~K`zWxu6_VOQm=xs_SjxrOv{xNM*DHIh;y4r zeydx~ubdm`1{lgM4y3p`d!!(I7nFLj@4LWnqKgTkJsj)YCvgk52eH{T*dh|L=$sRr zH6M?^>}VnjPva6E;h(u*KJ@UF2u<)4S-r7a&X1eF>*Io&*hc}CxhY1@x|{S?V~oNmP9j$e*EWs7771fyZj zx0seF-2lrrTSB+^XRUVQN9Hq+gKLK@mr7h2`pV9it$r^8Oo{Tv&7#Gy;IPCnMIW(8 zMi@KhElZW^F47tTG|~e)ixr5j7knLDeuRtXj&>XTpoNpKfmL^{6if^8ixvdLi6Cgo zT&it@Z^EI^Q3FUDFojOBH=t%sf?(1E_+a)HR?9g|1_m7R)0;tAFte@)t0K|L*~9Nr zJ)E>e$%C=9R%fF`7Lt+bS)vG0x<-!B(p^~*OZvi(~s8l#3{rcuLpS% zdOLMWOb;>43bCIQGQj5Gw?|wS3rvn^q)zkVJJD~tcyD%5%g6IW(ZsN8adzh0zyTHu z9x$!9Bw}yh&{xh{OT&bcEpJvZ$5;9LHmuZ>V|hac5v+Q+n}c8$5q%&JbrG6~g|J&o z7vLa{1`3>TWvD95V?v#{yBC$9JmuB4ZxGtQc3p4=+^z>!{Dbsdm-%=mH#<@n*%vnq zBVwTkr|Y&}Kg<0^pX_jAPR09P`VRg}x7Ob+V9PV!U1tD;mWKZgxG! z#wVB>=gS#M6`Ai3%27)?;&8r|ceFm-`yrrma%e9sCj5zT)^{_)(17DYp8}998~r$R z55JQ9og}PPWr_*&#=2VBHNt>s!R7iLObjJd160H*3!t+S?ZI7gUDlP_Zv3LF@4_mD zL(Pey9X?Dl=`t{i-zyQ5RKQxktaW%)tHvfBNz^>q;CR|pVeKk18AcM}++O}^O@ArZ z##{|^sH@^>vuHB6W-fne%tm{+x`;LTu(NwwUf(#SBfNdJq+$Sc)r*h5X*SYicw{qM zGuxTID>j%OCuq(i8_QQ^5a9`C=(sT0_0?;dT9e!cxBJZKcIb!0#J8Vbtu$qVT#ZvB zOsP3dW#}{o#!u<5Y>^pMgq#}RYZETCx*X~|E&&3@v7F{UY$wpl`opvrqpJRMZ$4Jc za@p^Gs>wL;k-a!OV4rVzie9@qS5qnu>!rg{O6rzG+5Y&@NVc2Qy7A7>%AG;?W08Jy zabx>y44E`VVJC+En*0?DJ^7-n-u9HcfcpK};=K(59PC-x^x1MprJ9!9c7bR@`uUwb zb?2Xjpru19j&j7pc2Lst=iLF7$#_vwZy%c+woEzv&=GgH?aw_H5V}cZ0yzm3_eNyMVp`wC^Fc&cAkBC8Lx&E4>&0hgH4aE~=)jF5E-^L@yat{x0+q0qB zfV^n@2Cyn0=K*EbL?;WiyD|xLoYAIJqG)*{ei=jo2l>X7tnmbOtC{`mYmJ&HXwRH` zckV>-7g>BS`M_pNZ&Dfzs$S3=k~@D_uR7ikm`-=ziHUL&1C>taibawNn;{4fbW^;P z2*yW_E~wf2c!c_rsmy*TM-R=qSfhLuEmMWSYFJ5i#Xc05r!%BkJY$a-ji+k#^v)6y z!5X9O4x2VbSuVDf|sydY~;>R|9xJAngPGf^K*hD1?M^bb8sMzETla(XO?Q zHbky$NFjO4<&lBk9ZHJbI%8HQSS044_y*%>!x59mcDcA~$V7#gX|hF-w$t=sWIBQB zyykO7Hx8@`8d>Xu?T^w3Y@5|PyC5`A;iK6t#`YwYk90>%U~E{LBhXbNCL(0H-Z*L3 z@@1^3oo$i&A(fi#!yA0{;E2TB3jF9He93_A1(Y8M3zjpLktT!bKh4r+6NX%SlD}-< zAwTrGeiyv48YX+|72J46m?B=Qo$c@A)80uXkA@K6dy&AXrYc<>Kr5D`P2X`M22A7# z=!bJHN0W%Y+REe3elpMZpLYg|VQ)A@Rx;Lfo7?Zs)A}@tI4si-<~^ZwIg!UnVS?UJ zdj|@KRQ!2dVxd8!z<2)mx@O9L78N+}?K6l1@A4g5s`c?%#e^Y)rdg}Y8WOeR6Hl!~ z%`Vyjlh7aKf@Y9wr8=o7KILwuzIM1XO5`!@m<4yl1&tP4Q6zQ^#!$6QEZ-G-Xh0>r z0Hw{DQ*0ayweVu0lfmAkp_8!(VEUoQEO*Nho$I$a4I*JKcN)0uz&oOWyf@cEwmK2* zO34hzT~XnQ=#457DYv~J!aX))LTsvhD^^`)dxz6>>0X1Ut%AP8-G)Htwg-9}e-9Gt zf5_NiRnlcK>D$pyU5!|S4?K6ZbsB`FbH-H>-}J7tKEW5TA9rSu!~caFj7@QW@ni;h z$oN(zeXb`<^m9Oe-r&?;cQ2FrWJ7e9iWXiCaX9v`&@oy}3J3y1>5DX##~AT?{N=W3 zfM4_&!RX~s5PV}x^1kn3uvlyisX{s#tL%5-Y4QFmbb!VQwSl9@>!}wc8@o`YM?%EF zi~-_MXW(ZL@b~F`9tQ{s3jP4&G^0A$AzJ&-%@BjBii8UC*K{3*)&CuPoH$gmhpN?N z^2L4$5oWf7>iMs*9FZu>yLjaii_-dxW9c+5lP6D}vI`!jeaOYxI4yto&!Rv=S5C>f zdSA=>!pZ#gGJ*o`G5acQRoH)h&wqcgFF;bJ2dm}HWBl3I{tlV{e(!+-_Bf*s1tY@$ zy4c^Be12b5#LiZ>FOaEu`KQazG1EVW`h6S zj=#>{fAtU+Xiz9L?-yO_e=hc4SEcY1l=hYA%y>2G^55M2<5d8#l>Scm*egZ_WsP}^<= z0nf|Q`}?!;Q=mSKpuPxj)ER+iS8PF+w?N^UX7ay$=Og3uiF{{4?81gucjV7~yt9hBm8wohk!6ITNG%S1RqO^aY=lQl;7bjLr%jUdo z-RNAUepPng+lEiG~gy8VqRDl9?j@sz5z2jz1!%)5);n9t?o|?o`$Fe9`GHBo0 zxL@alKtjHmG^>sxoC4h%s6FZamiLgx?Xh>RW%0AVCQmUzLZIH(rDpwU{^TUie4s&2 zV}L43h=~f}(q-XBPV~;_;eyv4*db|vBEO;t?>#P3&q-Hr*eQ^{ez)H9g&KJL+=%ig zZe`9MztdzEN!k3O>9WWhe)VFONUkk8d$wXyQ^pn zo=EeR@a5dMi8_#+?Dh4AnP~B&3VkS%I}(AKnHR0Q{veIJVlsuJs}R ztLQP`4dk~H1y=uKz}o>J2l)MgPJu>YFaA*}(zH?CikBmc@TYoDm}x^mlHBu*VNV3s zigt@LHa?1hEEcPt&?K?hnt{SBJ*dg{2B3)76!zf4u>!QA)2Esw|&PLuGXao9+Z=tL)gy!vZ>hYA6+ zH^$t2EId@%HyI97mlr>n4=M&goCq#`RsMao;xp_zoHz^+;S^dM9k=2E$J|1GD@|Nb zZL{O7tyZ&bfDWMJK5WWu`tz+_*XriL&u`U+8)oyZ<`sEvYw&~dCp3exG&M>;w-`SR z0+^CKr$L<4>y5UHk>ra;ooOD%4{j^z0he?NDYWB7EB1*=`ia0_4go$r-#bd&73BSE zcE$$%gTkmKZ_i^n-|{rN9Hz>rbE&%=Kp2251XIQKFeA{eX!A_>kIP=Ig_-0FE}i!k z?@l*aug~{G$i3q$2$`IQZb{K91FS@xu0yToDpdeU6Y3Y7X3?bc)w0zlPmW`A?N7d? zdNm&=zAJnK4gT6R?!LUr^gKSP@(QKDYCPK>mgfFm_S>6ZtH!0(dZDEkFrF_`eODBF zJP?2>WUx?k2)Aw|==@laWwKQ~?eTP(@?sZAuyS3oDW>z)Bk6y80qrB)oWrxB?J}F9wKkm!Q7+_oSg-W)qIFz_FQoFjQ{NXY^(BM$>)cTMn2lF>2;c?**l}xCs&V{+c)AX zfcX;hq6-kD(%tE+W{fJ)yx`2c_%#8!Ss7@beN0gGU|mAC8Px|%#nOTns;aMn0P1Fa z_{IaIG$i+Ha_Hk0*nGu%Fy_J(cd>K$=TXJSnq~0b=1`1!=6i7w;EWtAau`1R}#hmS)BxB}eHpw_Yqrptu@%9WNYa%l@6 z%$FHI?N~jOx8y_QS}ub5gLm-8OBA%vTU*SJq4_I5MEtt&WRlxX3Wtvq9@F^q+Ui1ngDkXE+1JnDunB!+b!Em>|1CQC zEBMo9@6|ob$9L+MyO>HVP~lj3X5;C^X4y;MT=idw8djH$xj!f)K9p&5yLwyKf0};N zcE4wJb2~gvQ}?LpQ~+^D9U5=He}#By%{vbmPsUpFpS`}e6MQQ092em*oQP)&K|DXCvBO7w_zADFIlBJ6t4F0n7H}Mi{hClL z+tyMsFsG8!wirrIrD4sW0zASaxWV5hJAf?kUu8725X?L-;6&u6) zG1ZyG6v#Wd%(@3*f|6XAK?rz6QoI(^;*a+5dcDY4lrH;XurQiZBWVE^lYO7)<3%f& zbgLGAk@KvJUT352Eh?<{`}`Q}2kHysk7I319oas;dv&}KD)!PrGq3B2iFu>Gd_$O@ zG@TzhHa)-oG43z>4N=h6n9Z@DiKizv%1VQC%OoTKVv0jlsm9kq@;}u{X!P<(5=G+!`zz(iC-jm+ojZmjAMjQ*{4U((H*T`{(|xJxNRE&+2Z)Y?`mn=`NW~( zZkHz`66w|BIzMMoWVXI;b=e29P1*fGvLno!+YgEm~Qfd7%G< zH;f<_bA@%^aikeng=gswjY~p(DOH{HqjX{q1t@-Z2Dbx1L5!&gNdS6p({v@*_(FpZ$HF7WtAkyo_zmd z%CrJHhNT)~N)^@6b6aySSY{cruCA`>lBk5(WT~tbJb0wdKPhO}4*}Y6TXR(#6Q#0} zMOv-J7OX-n^vZ2UH1oNf)xu5AvFp9dT;4~3$6ewtPSL*-G|R%xDIV9X9@t1q^vO3j zI-N|+2zkuJv%D`|F}GJdB#k}sywts)HZW5JjO$aXTrm6Cx*?VB+EnxgzY}O2-`t$^ zXPImhI&J}jJ!U|F-+lWl4r6HxNbZ@vsn_4Z zo?a~FQrBZRhwANjrH0Gc_hkvuw_XBMBbP>t7`2r)0ec{wg47o+l;cb0BbnwCDQj@A zap*wXMQpG-@geX%D0LV&^314}uet^8T5SVSNb*j@8qY2~+IgU{_Gb!TVPPA5hqA)S zb16%`9+6LzA8+qtUL>&!{(79mPJm6wsuR!9q}tmzx;T=JJsXHOau#q}Z&!IxcyH(~ z`<-*u^Xg^1MNJ!9z#ZmLLgKm|p16v!GY+s@pDDZco|>N5Txj7Qu&Z?SciXoV6Ch!w zy$w$>LD zdY1%R8LXkJwOAP>)vk6*8ATaPDDWLr7aJ{L_dMpx8N{rZrgG3;~aaICEZW zVHbU>_i5F;H3%%V^J67VQpp>wx96^>mF&m+@U%XVKv|KSIdOgEtdCTD{XocNdpe|k zJuuij|EA4fdW2teuhp@j@vM#KX36uyp}Jr++4S^HIPw0bUtQ}mpiA4mi8$Q4*}Ns+ z>bO1TxYye^qLr0)e~X@Wy@|M2kD8^7(uY`K%zni!vZM0=Y=Dteii;CPuM4vUn=3+4jbvt=% zA$Zq-Qc4;+tD5fo4BBSK>i$byh1oG}#m9_3N`QRja$1%1Dv&?e(KgZF0@pbQv+yd- zF6s7t+4duCyJQ2&u_Qj6yk5Z(Nb>!h{m}l1#Q@#QrXYr6yx-P^^I)a4!u@Z=1zM*3D<`hZjwLT+^9RBd3(M(rBg_h4^c-MP&q@i!QXbi%6y=7 z`vAy<>}-Bx%G9z`9VSwHdsp6?A?em{|}xc8UIm0pmWyZ^{PJiw|qKP5X8fGe3GHiKT{%3%1D2XyVga9z1xuK=E@2p39PoBqW{S&o%!e`+?P}A}SCh0+ zyv`ITpfRBv5Rna}R_nFbd-b6_9H>ONw@QBr z%U@fm-wo{Oz`eHylE{P2Dbjv-QcT8#dTI1l=AMT2$9l`?Z3}E`^|TN4fD7V?KN<}abk-^v0Bv+MvET~FZb8SYR6TzGY zV@K^5;~i}RFp_>4c+UHa22|Aw2S(hG++Y25HV$Vfs9&Ka-waM#Mod?{eVb*x{1R+z zuua_ZuCQ0aETX|5pRY*uV(I~kfJJ8J5b6r`3LQBSqw<5V>A=IR1`j*pxxRU;-SsG& z-bzSljbR0)cB1@5&zaCU8CwsyiOWV=dqc^jT3sgFAo%Un>oS{y%zRQE&)>_6nfLDG zR;UFywtw=G9)BfjuSCZnrrD-hFdX% zYYgs-RHp&>Tg&0qCG&npN6^6RJkMY%r;@TnC%`&_bD*Wjn+t@Bsk3~aB-Het1oA#P zmmHcA&tTOG7W-8p`SQLr%2v{A%cDcZnI1^S&XTuM(h6hI@Nde_d$&hkIg_mN+*Jj( zn|cX9?y8Vq9#y#&?qNeA)B7(Rw?dKNv2Ac8=EQk#*D!QKeLn-jYiHOf2X%LxDI#8* z$+i0vj1uLDpBg-tXy1%TH_!AM8yvH6`257#xDw9u!Q?ORgvYjnV(OgA7X$U3h`|Ej z3O{bl2Io7^i@w6&8VH>TZzI#F1+))H-*mKmK5nC$KR=sodt#O>h|WU4yPs?8tjjfx zQ=TOh?ae41K!UfW94M0Eg>gVrqVI5(OjyXVg_?QjST2bPxC?c@uy5E{#t23qs~IQt z7wD?%MqylCZtz4@<4)x76?-&8K9RsOnL>eoT)z8|99jtYXHmv8{V*r)#IPAEC@EYe z>+TKs@+UpX1RQ7+rKt5=C7_EP!r=Y<2|d!nN|g=vZ&awPO7?wAXAOLbT3#6j`La_< z!e%OD@N{2aC$XqYpb)P~^5}vB zUx`5bycV_?%9_MLa=RQ^HLEJA~ zp+-Aw4sb9|qVzoVkxiE9r)eL9I$lBf!Lzf4!2j4M7KN3K(A@e)d@(B4s>mmo-UYJ@ zWMClxPX*NRm2CearK2VSAB%!m%!^pKwmph3r1}puq$*kLy{8_8nH{Bt9TBT$b+t2K zt&he&%Te$+fCY8;dMHa-)R?-5$+z8Oc!u|CIIx0d$ZRZ8P>Raw&Iw)QXgIL~O{;zF zjgar<%jV?Mrc*y9E%f@G>%m1>o;TvzbI`nDDr_DHZrTasB`hnS7AAZ{DEC|p>NQGr zw$x}_Ug{8*zhFmrm1>VcR8)wQJ4}>%#$A~={;Siz{|nC>zc=@nMQ=ynD?I4g0+*v; z5lPs^I3g*>Jt11{AHjP-nghcSo@X|zHIKE1`&97~Kzn7ab+_1`xE`&0H;BIE7>dsj zdI)akLdl#QN1K9PF-u#Wjc8$M_1Xwpz0L$7jvv^()ng)ALv zix>{cPh$44{?31q6>@9bY)tGn48AI3y-qqKNEPT;OgF>WIKygNZN0_Bu(*|dyAgu% zWbcYHWgd^bscmPB=l0OM7J^a!+qHd3RvJ}}_o${d*dUXL_x4=FQ-4Ear4J6H zwISEAP1OPOZ_+VbEq~UB4T?J7h6^qp*MnI46`HW=x(TM#api?A9ZZ0eR)mVdan-o^ zIL5NMjo<~_1qCfE?w^v3CX8~!H?Cf%94LQZ&kphwnh}`5eAuJ!A|H`JMU18>vPvPm_{Iv%~On=h1 zs+L5|b@OR5e*gu(>0`iTaM|$Pt=UQJSjS6PH+v-7R{g4K3**h*Dv<&|)N41b?C91v z&eLo=uR?PL;fIAab11NqfQm+tZ^%{Vr+ef{B^@OxZ>gq=pheeUF^U{0=zcbESC*%* zA>ug^>8Aszf;hKJHswwO^iGtRgASvSz#_%QlGjA@tCqGotANapq9;-5T%aGkf7yK7 z+`U*uXYCgO81$wGWO$^GU~hv}l&bFh4LXSc&UH_&v@cc;eNCP7WA$k2n@ti(3w$zLF&wmdM0wgn`fs;0bRqi>9;Pk@j3r{fYfn zruGR?{N25On3cHbD!g145z~YgMS9JX1KRwBg2BTml>{&kp(*V`0E6snqRGDW3IaYG zH{K4IaimP`mN)0kl$t!BW;yC#iI02py3KiO`IR{LABlj(l_gr9PK4G#U+`Y!ba)55 z1(2?1`UN#b&y^=@=(0?+og-jfF!cOgd-T(M>kF9MeNy;*d7y2e z{j6l=Xr@CN(TA8mvPj|0E@4I#2#KoY61Z+lk;m_1zYBI|(=s;pM_IZG6Rk>O>s<48nF67Sm;3 zbmkrw&n-WpLKp&FErnQ=O7ffCuk#VVlxoeL|i2A?Q8lEK*=-$eEn zh6RRs!G*_bZ3TlDkxA`~W3)hnO-|M@YqE{c)9=Sw@harxBt8|1!35zFcY^onY~@f$ z>mdf-JX-o!X~LrPQDTYAQ(olb1TdIw$*+TMx5;@QulbISNFZET%DBkoc;mF5Z!Ql- zsb{%dFm-Ssa;~os5HlYPbTPM?HLXYPej-3Dmg!ZMtIa_#niab^;$KrIKWI#ox4ZDs zK8?xF@&a4YcpVG-+*Kc@7@3ai$Nhy?(KjNQB(bAArpS& z6I4J_m|@@f!8Gk%%R^$V<-9y1G_p;idoP9K?(dks_Ll)5YN^NLxweSghkUNPOLBxs zfen_>v8cc%52t-5VDFhGZ=g%3@V#bFento(PGhmW{!mQIU929ntpI`*p)}a|vG#35 zY?jeKTOpLh9Tl%He?`2N-#*RYe@(X_YVdEeK$K`{}5b*c%jZS}elSBVlo)wpX?8EAjYBm|wy=a+- zDj_PIs!&%DdC4)+Geg8#+Rnf7IJvd7x%izi!;j+CvX4%4>g{<{5-K6D;Gu&?DKhmGsc|5;K5q^dil4r{J^2AU)qP^fALnD%OlnBaJJ;uZBp|>vpo|);0okm~3 zM&5B#Twsyh;Utfm$sDMGcT8|Dy@}g-$i_3lQ5h%rk8OaB zT*4u*dV(MkrGSM_GF4Pw!b4N9^$%PgI!D=_P#A8{o8oB?job{`F0qm{wY-c)N%$sj zg`EB9>_igF2niv@C3qABX^oiQv(l(YAt&W2uD`o3vy}|*#IeE>YXR{W*03i_yRz;V zvJ-IaT~*nqwH~*D`z*V3Wk#L1MpAxQU9!0TVj(lPV3^%jR6hvYuqgW?uY6By*#f zQv(d05pu8P!w8Qb*|IEl@kGMdR=X+2n6IU3y9=M*ZsCYN2Jl9lMhQ^e-e)t3Xv?qQ z&;i7)c=2kGn=)e8({wmDUy*h=btw6Y)=$b>=a_G=KS*+Y-K~zi6gswIvu@c5ZomwV z61uMxx?Vj5*%~%FY*jFBFMBSAusNPg&``D9;BvHVH7flDj=;Km2Ec%>?#o+@MlyMA zPQG}xo0WMjR5ajuo;f>axNryjW?5)HFmy9@5C1C^qS(grHI9=Nm?03nA0)-;UYc!g)d2(sA zEw6;${N0Xjq`7PST^VbCv{VyP?Xs93<5!ipZ^I|X)@fc^(~ zO9~yx0jP9ml>H0JOstj~m>VCL30%JZ3!W+Wd2ST0jeYpv@Ff|Fk2nC3jM)xVQ2MWx z@E=nOXr_uJu$-ps%}f5J$ym(KXu-sWpp3t#oydj8;7NC`B^5?rJHZ__am0DMUe zFLo&cK*9gf%V@EwXJi{UWd8O4`V|zil-%>`*|IS#_~$h7AKj&}d|o}oN7f1d@xy-* zbGbCY=>0scuT=ZDu5dp$2;H^*pKatn|K?}x^U8A9o@4m8t`I*rC|FSY50C0ERL!4} z@cSgYT8@L_F?RE|ZTYjpBNzt<@8J66C}v%2U8Y3UAwVE1=wI&0sx6iMED}5xvRPTH zhuqapE96Rr2~6WJl=8p2MUjsSwhHubIebJ}h+U0AJdO$TS*{fEHSOGE!R$Hr9Qp(L z`oG3lEDssNEg_yr;DZ3amSOFX_iNGN`$nmc$^4PkSfjRw=&p7DW<*dJ!SE@5$!4bK zQOuF9zz_hN^PC*M0W5+{7Q(fveV)V{@9#_*p7gXBRKd|lYwCKM-oiU&D0T9m1F%Z5!XyKb2GaJT@ZfPF@dkZu%jv4+3>w=|V5IAeVy$ zM!<3}(f>v-<~>6kqN8Oky`WlF6fT{TTn2H%W)2*3u5?yz6Kd88_4qY_c-e7CqugwW+9?Kt{Du~gxv*QC^6bEx2jY)fo1dBhstDvMm|d44 z0Q&H;_K>Ma?R#`&S(mTcitX2gO1yFUeEjbq-Aq3LvnAr zbp1UD02Xbn_&g=h#R;u#&PQMtPsJdv_r?La_BySG!;2dJGm|k5)V!gPt?x29y9|9g zU^kU#cC&0cUrbNyvB=KC)9pTM5s){ZuP9+Ud#y$rV~|P6D_QBuuZCc;T$tH82T%|A zz0SdCyVLW>jfpv~ue%&F{h zI8RrW#v6|Y0C+ARAs9IZgVhNfwi8Ya7nfytR3?*&hZB!+`LVRl@3I(EFM2gT-;QV%seFIM zj8YzlyzQ=46$xl4tij{=W@@@JcsqV&_G!wWCRSE|lO;_eo;-_|eU zKefx^g9kc!eOglSUAly4TjhSe=2t8wNMNT5pzvg`A|T)I0Gr1BPAG^tTX{90+nf&I z@fJ|Hq5%$*{(h2gQF}`A(Jkd>k~nX$fd3H?@Ta<@B1Q258Gdx-3*+$)I(Jsfy+&vg z={@t^dnWq=AfpTjBgKeL<8c}XpR3l(TNE?_nn=knlIY^7V{V3=yR8$=lH1^5dMfmBuC2-UjnSoM>08Q<4d%ggM}WZ)W-NBz$TF*24FFsF>sHt zA>Ti(!F;~R@-aD?z(3u%$qIk+ykts&O=Ww^%@PE<%}an1C45`hl1i7NxL6YS~y#l(y9V zMrTS&%FhQqvh($zBzKUCc`0Xmyk4fe0QlE>?(zvR@I7re&-^)Fdw*K+(FDK; zitCNt$L6&iJz=7T1Gi~^#{xt4c4X3@2pXvCM+1xtrrGibMw(@h?(;Hbzn0U$)CH<} zzm;9X2h+)In`*~#y_<(qa!Z>F|Fr|2e$medU~5RNLiMM#0F=Vv-hSboSMe=JsJvd$zd!1}~wXP_= z=4|zTSeEoT3iHgm-7nx7r!+bUOi~tQB2#X^`)K2R>%@Ai30c+BYA~#EI~(7>GXYFI zt38jspAoaSx{pHkenf;xEKe-Qc#M{No!lbD$0=WluV4m6SZy^DN<1>o2)r46 z^lug+8Z8ZN`puMR+Tfdx2PlSUWi0G^d+m>4w<4j7_c()DybVQ|Pb_~hi?-DNH)e4_ z=*;cXW}(_9#M_)a`b_kx^hzkgy&RYB-6zbmzYhr%1Xy6kXE5FQ-LCg9-edB=z;uzv zOUICj{5{)M45Lq&Qg7%BRa@(yBNL$t=xPGi>!J7XYZPjU>GdDyn;arAVkHA`5?-t6 z`BWYy=3LEai?)*QR`cJda2Em z>}&M6U_gcpv4MNVh!;-GtCd*sk;-nL!fe^U*RXP`TyGGq4T8uPeLPXqE;wv$>jYSPES z7nXcmEc?FA+x?@PjV4cV?H3CwNrK|LzE%JyeH{~GZ}0Pwr|1~3uI7SO=&96c|M!@;oTFp zN`|;Mn2C4g{pr3xV1{D=50JtBx{{(#E(%v~i+5`$Lgs zGyN4HkKa}Zjmr9KBBXAr4r=gai~UrChG|bjo9NJiaAdeLo9#XIula(kBBPBabu%9C z?mh+8DphXnvTzb%iPP;t8z#(B-ygYJ#zlH{)vF=SDW~|OdoX-C^1otZ88+kusPb!` z!X(X~&bC0(eUT^^InJo?^jY+V5`$TySr&v<@BmPkHeA{My?OJHB}x0fwE@S2ArI&j z4%Y|Dzc0RM()oj3NYy(rkos%TCx4Bt@gxn^0!4gfdd*7v7%s~Nm;$1hP2swHaBdB4 zA?6268J_F4$c*MZ`9>64yQ$xls$zHh_-cUJI*S4^$a*NgLQ}ThdY-nzlDsb*tuB)d z@j43b=rc^iYdk2Wp-t8S&*QdlS;&~fmKm+JUE;GCWu#ADBY3>F^Wtn`(!TAyD1=-A zf$pe;`(h3uIR^wN%58>c^=6l?pL;)>5nKbrgxD1Qk%WMdNFwYm3@3x{l@f@1L}uBWw-FbIk^G!~m+AET#0X0pSYSOd0D^Dl=~~ONA{0X5}&cY8Y$;h`Ol9iY8M> zHIxL>M5tdYy16wVh9cHH}M0cQUW&8&=ggZ z=l*`U!oz1L)xf_p*zbn{GYNo{JN>@QU9}qElk011O7iBpfB08o1&Jv*_6*6eY=i?TP1+5-` zm>eE`Lh959GH$^KqM*^DqjmD9;Pl5EeRH4r@{;^?=3|gE3PM%R3^ZlYgc+BQrIx`M zsgP4(T!=B~&d2g}x~yYxrOq>IaIwjzIj*4QOmUd_i(sC2H|7k$t`}}P;C*0QmVehTF;%c`>TPWNK?vS7%xH}XCNN@rK zmq2h2?(QDkB?Jxb?hxE5+}+*fOxC-;v%l5$`T^(STtRD94Q9=H<|AYD(MS9GBv?#l zx$%lP{l{Ns?Q4(NvQ7Xb!$YanX#FYjheDx5ZX^2U0|fo<=|&i&V_mnLnZm~JbmA~z zqQ?=dny)yBiMy8OZm}zq!yBlYs*K6v0`wt4>oAUx2DJxv^=H)HXc+D1^3Ee$Aj#=Ai zl<)Fqb^$^K`~8>oVz`kCBqgJibF=HC&2L@TJ+v41==*({sqE;(w};ZPWeK1W(+hk? zRu{g%0Ffq9_Ut#z%FR!Dn=AknBR9pOFAlS&IaT@d+3Etl4i1&7C0Bg%B5Mw~dGB_a zOA)S`Vnac1>%BPlxvyLt@6m{?1`fjOo9gGRCW`!c9oN>WcV;Cyg}7XT(8(Rn%d@Qr zX~_F58}0Wh`^CIC=yHa+%C7GmSA;V`rRgJr_sOmtQ2G5TPIy%>wv#j44wDI%G`gzR zEDsSH)pjGb0zi#tL~IaR930A}>=JI8fu4V}b*uLNW&^hk>J9da(>2j)S`onxlTmG# z!9uMP#^gu?xu^XIN+4rt-;#WDn{BHho9DTGzRszL`h$x><`Dpt+6?Gz>{ejECFZh3 zQpEq9>3;mriGQ&Lc2%C>_nsqAV0!D;19J1h#IzaufL?!NIj5&nrqi;G>Khb6U?|6^ zx<<)9OUi2Y$A$6EiZ@o+s*|cJ3d}wtHbLlYtml4PeiCI9LA*+$gb$;%%=jw8T-K-S8qZOYY9Y4fsp^koZrnCz|8y?l5a~SS<0F)q8nofIfP$H{Z7QX)rv3 zL{{-sJezFZb~ADSuC^84OkyfbV#LKFh1Dk?3?s*^nIdgfgtdGziDYQsMrFp#`if9gc;U+gIv15lg^(#x=Ra-n+oiG3O)ptbh`BDpOj9|Oi^Pin7BlG(_M)gAp#G%oTf>Vvci z2F#BSSgTJP@>J~&YZX^OS#qVI%YOJ?6K*91O}4dOz)gCKB++2kCb#uue*=ktFkP51 zVi=J*RrkXqe?SBHU(=C|Dt7&W7RH}9h+3Eug(#wC4qy>voaV8Fy0REs!S)6qyORJ^ zFA*!mH;j$h20rDe`>okk`l! zQXBE34W74p?=}Sc%VxxwGc1~LDecw%6bHD;BHZ^_o1ah>PII}n(c{sQOsDP1C_~`p zuhIwXnI!6nu!{?7B9V3fHqaYP>|o{w0E-$@Y>;O=N!( z-Q-$@7HfZy8WAosNSTA~^?Y)Sy!2$hvtZc-FQ^4tq}jQyA1N3ZnzQQy(279~_A9*v z$&W1U@Wb;-A`wgcwOlIVGgqrH4!m^F5^okrcdokjufhwtOEDmXbWe_JIkxOjs<4Ka zH1$w8@8eeLrB*dyST8byo=(3Co&sHu9`+;f^$w0M_Emi$9+$(Bf2UsFlZwP1Y}C9k7u=4vDhVG6yA|DS=qFev(nEOYf2NLog+eGPMs+{ z;TE}(n^Pps_OYTr0q&^L28Rxto8iWyS%K~W@4?VE95T(a18}(oAgPvA7GOL1Twghq z{t|(DxFoJT##X@#0Nvj}y6dfRQ#@og;uT00!gwaUHy3g826S06IsQ=#`v1;!)ej;q z)&PpLR80m%U}(8{QGURg_2B~Hy$ja8N^y{-5Vn8-@vz%F401k&`Pzf;k2jWCBGtk` z1t}rN_oTgn{Vi#kL#Tx^VD(9v1Nj10YJqv%N-p|%6otipwt>f48~kGokI>_UZ;bh zQ)fyNKF8)uMJ;>$mfFJDQoVZ9^CJQ=7g0`z3NsZ^4=U8BfIq|g=Kd+Zq7^uwH0O_B zq1>nWCP81Ny6d}7vzmxjdJa9WL+il>EW-reBf^=@TYeR7ZwO||1oYQc*AHSuPEgOI zKs}~Cm(IM?k!8+c;v^69GnPIq#j2k3`(~d@I<)y(Ex)<|{9o-e9)JeMDYX_2cF|9` zxlJz+6Nv(^9$O!Fcc?n5d_(AX*=nXSHl!a)*b5f5dmn^E7Rrn$(4eSlRxauz=VFq6 zHN0wlp7d6Z1l~z|`REkBN+-KLRC*c8w^lA)o4bMm03MVlc9HSxr0GPSYKUuDijh%? zX9rQAFIs*o?VAk2)Re}QIrKoIMgxYyoMP`Z)o-TdZ!(tz^1?}pB%*6=IWSSNZ*bn{ zh=L<6n2B}0P^--g{;ujAbt&h*bQ&DsBKsPKaapX2!D=WUzyVQSayAPQ`3sVDmycs( zvGli;?X;j6{VOb|PI{yR2Tn?XIyGo$2ngExa_ret9P6gxf9y8Wh#zZOy1mx^QA>e? zl2tqZQArJx7 zPIGlY60;jRa?Pr`6xuq91UypPkHNU!j%Sbta|}R7hXyIVr5fOrk4vV4~Z8mVC5Ajs*jvn5kd1;~Dx@8@Cf0|mor6f} zz&V~F-w$7l53n`cd+C5W3VQ;!ncS753oF?(2h(bnEn|1GeZLb&!SYgMtI1b=joD?N zxu}&kMsq19(b{rcP{?%&RXQ)%l^VIdCcaF|H=PI}xD7z6H>r1U?xf8FkL^Wb*F;tT z7tpWd)01)B+!+A1_0&VBFy8&%nEQ{pAD}2Dvuo4fMi)S_L9opSpz36uyg@ z+8Y`)Z-PpRjow`;o{_iaWMzX=d@hb%#J}1-bX)TFZB(jC-|@v-7nPSH94A57T6L>H zl>rr=t0WJH8|u9-^wCL0dR$Q+0tn6l(%$?&%;ye!QcksV$8*darT!8xPLb*m7;98a zO(=)C8y^kvq{f(_hdtSZ65%@ZeS$~OM==CJ7@ z?4ZWu%eM}X;Dvv}$4;z1O}#l3*8CBA9@Lu&o2jp?gAbsG9DXJc!BcXLhHZn&tIzln#+;<*3h+wsO>?25TfuX_zDN$ z$n1lRMW4Pceu!R?V??tV%6qNYQh9UOTJzI8F|SY9I{uy-&w;9_FrAiIUY01|dR2 zRu8Ev4w4mhTW9-#KWyYaN0<`fYKB@{tWElBLjvWcv7-0AUIse5166$phxw%XD+ut) z{|Mc$3dWwCkQ;fJbDLP9qe15E|IB*l`uf`+&y5a&G{Zof3tLp!LeKS=2jd+T3{|6` z1#yihhrFsm=3PJ?6bY&I%xvniV+fP2`PG$B`VZJR77)d)_jTWmU zRQ2w94yg5-dbo(G<+;D$LAYLc(zU3%|K!$=nLthv3S)L7!ffV8)0&O^CtI!Z8u7@7 zD6UllZkPKXHfRHxPOjogKeznY)3-zR{L}oiEZX2XY70TwbZ#iW@g#vUk?#srMkr{0 z|NZHVZMiCLq>~};@4D(mqCOBA`PZov_%?%MZQdo7Typ_#Dcd64OTEC?5T?n_%3wXe3%+I z9!@pFH^KYF!UUnGlHaI(#T=|{cnUZY0hGEd*u6hoFoYkY*(ut;SZmMM{p2Z4B6lqJ zwF4yoZ~3q-;FHys(Ff-m5+xUb3{)c}DyxUoS*KmExRkNjR^19ylE4iV5+R?o`D0H- z1kmgWP)Mf6l}Fa!qd8$C;?GsJhHFb6+M>V(ZM@5Yms{O$`J#+)8_$Nyi9#{W@2Q*U$J}POnD3*7GX*!BnVzrt zli4f-HLxsf&J{|{wxoVadwpNnM7J?9-aKM`n73{hA>?&Un_FtKE57sXLwA4CtTr<^ z*PS5m$sA2Hn+cYnkU*V^`9tkLH|`b8>74}gi9JsyjzOI*)$*|mRi_Qeea?l(|B&-~ zq!fI4wEF_&^h_sC4Kmxqd4MCZcz?!+%lVcBT&s#4i5mKe<~=kp^bT8$h{Zc^J$EA8 zCDejLhm9atdfaiMnc_8e{*aBYbnP;$d{>Oi73O8UXghjPT21$o=jFZFHnga5tD|i$ zgO1pXXnkJ_=@kDBpPf-VX)^AbA=1#1jEMQ_x<6@5Z%)3Y9A@A!`n81Qxoo$?%myPF z4A;_B>x51|rVd!G$#`9d5Q%xbeSWm0sDwLsE3u@ZUBXnQ5!bvlhNq*8W^x=XkPCW> z=E=M)O4229SSGk%9I>6jy9ofM>4M}|!r<)pH$xv7kXfK^bP{oqo1bqnMO-gQzr(N8 zE)X~yD1<{NEtstVX*9f3u#NE0DwA$auTAHZ)PufRVK)1@+8|KI@fFTPx!s3FUx_T@ z1j?N2v;-(c_Q4I7O)@28w=J?*XdP_WsgJ@POpHg>f z;NkBQ{9!|$xg(`I%W{ZObd_>tE+6vrNPlm+zb)|4|sL23rCO2$~DZ7ko5S7?lL-`4nn&j_g0)8;vWsVK4AgQ3_EcuA8goQ|0rR+HM_+teTArpbcJ6N zeRd^j8%!HZy@HY~13)fwWefcV5$`+FdSBF7mA~VvTwVpqW=MAki7LGH!?>kx;@c^x zrn6rj<*ocZc>3rxFce?aoZ@yJM`y|Z#gO>Cyt=PmA{otJMUX!H673&w7ApdO6};uA zjGEI;N-?krhc1ENVt-!QO=z2&pxb9k{Xc+-4*?*C0*5zhA2PgR4Y#zI3;v*_3-fMw zS{f+#d#|S>?!JiZZcXb?4Q$kpUHVM_3#1XL2a?wQVL=G5iz9^*ridQ6o^Ep>W4iu* zceu`q2J@OHi`}(qZy&kQ<=Hfc5KwbdROVsTpFllXqB2tTe{dBFJZu2d39}YrPXE8K z6mQsO;J-MB*kt~fm;P0oUvayAG4X%?*#AH}pW3CpMST(x|6RuaAB@lc{}2DabW2}h zweEGdc4^xGO+5YcyN}5$HCEk#dx-eIM&AFBULOVj4Z3}wn$*MikFWTjVL*}aI+O5?feJ31cg)&Kxa0St6cx(FL(a{SSY{o zUfud9Dfb_r(K{7@1i8`vov-_kmqZv|5zqu-sAl*7!lKy#_iZ(=!}7np6ubpoO!qm0 zcj7BkA*6X8^V7L@xB;+5dd~|NHZF!@q9Lp8(^WUt_; zHRh_Rq$N6#KiahM#nWt%TAO7Om;FN8Un(!h_QvoSq;K=5LaD^h@pFx?ikuon91)0p}-D=R28ArbjPVRc$8yY`mW5)$UoNJz^N*78C1v>5-kF7tS)e z=4$?V`|{B}(jyXL%GYO481|SbJIin|Vf)o1_tToF(Zl|9@sGn>q^fkF77pQr|> zr{ccIM`ive_4br+xim5$T<}GbEEr$DH{$lv@hkDsL1+8fzX-Q0epn!R_yOJss8^EGnUs3o^mDIz)1XlhDP?-j=zD=SZ`j$BB%Zeq`P*`=GiB z(e+|)yTAhQ^zlix$k#{joh)F3bFd%RrsMIr54S&=mVDJqnL@6yT~6jIDzz~z+ixCCOG-@82v%nTXEZ=!O-sOiA&g;IKd`=1hnN6Iw+x6#zZ8U1J zMh?%xMFw`hr`vo5o2n+4K#?uolNMy+Ap15c0i$8n728c(i7vS1CPP&Yr17Ak zTjCg%<{J_zB_d*g2wc(LH>^V4x`f!5twongmjf;|8RxcYOVWL|@wyigaCs--FpJyC z@c7z#@7fCNV#SKwFSDC>}_DwKp?)}@vD`W(zr7E$x$Qs25=AIFXwjk4a|owvRN z#K|#<)#N;Vd2P>)?}Ba1JvSr(Lvq}EYRwsjFBD!v2HARp0XL1}5B!o35mSvScIs`O zzlL#QkD-Q3CaiU}uV|5QrCE2Fz)2%`=(I_A?xFZj&)MctBeLz-~t8pvXA zhVj}NZsZOBI9|j!7uH5*mra@a()b<8<-DINFZ^Kzp!dJug{lNDbYTcm1?YaDvTi+V zv_GELenvxzfrQ~CG`sw0`d8`90N+-nXP1P_V?`g8lHSKVulx+cx>1G-;ajRicwUGcGQwKeSh)k`ciEJ-B2{x1t3hKo&qni zxl+kmmB#%fy|8@EqSZnssbmfsjx3=+< zUi^p0ic$RQ4jIo@$4hZ?ZdkL9I4tp$!t9+o(nC1Doktyca0Yxjwf$vMx{p%)i>V?`&h3{)Bt?~9ZqHe!TXdN zT{3%K;`f&eZBa<(0rW_E-Kpl?!@$ZOyz%HUvTo;=et$*I=RW0*(Edbq6jr$T za;OcL7C${nrpbz_`34sjCmIths-PjFjPnNRcT-a$&>e;tCE5zC5DgEGJ}yV8*zjs| zF-lIfTWKM7!WT*~3?z43aoZQ%;k6wFdc|Nv<}Y{?+niRQHL5M(0I2F^cMD%i3O5vo zUc_m|AzwB96~n#1xma?eYd>YQF2c^Fc!!?C; z!nFB*9P+$49%iNSRt~uT*wAzGJiP7Cy00gK8$%Z*maF)xH^Y!TJ4MU?BJ^>3fsuBK z{gElnkYTXp(O0j+a|3Ujt5eIJ&F$+~a8xAisnEc7aOTmXY@d8u94kr*<)t-UC(lB| z0m}SSkC0UIIoCk&)p{Yxde!I2Cg%ntDdERk?2^Y_?9X2tzbj5W_uN-Ft$<6rnC2k4 z(hn?x@sz|%Xmm&7wCA11#&rO zL^mx-x_h^fD~yYi!#UkMCth~L9ahwc5e0id6Ffg)PBbJ!?!F35KjQiIdDT<5&XZlR z-vB`~LuZk zEvRIc$sPokp z9mI155h8S``7)_s%z1B}_YYWCk%u(ILCkIUq00qYDzLENfb&HDlX|~AIU-3y_KcN} zU^=De2>R#TOV_&}9CkAZSj&xu>_yra&5VcspOp$$ygSCvSFa;(R+4*bA$u+LfOhlC zh7n`S$+1}Bj`Ua-v`33$qwTf3Aw{$TxTF5_r0MYd)#W>D9DFAAH)wxcYl`4`8N*F4 zFyhZ^(;J8M){(p z)=iv_V^d=!aZEveySw~Q+;HVwq5%1E>L2E2vA8!J)oK<>?$m;1mqUw3Vhq)F@3zb2|kUCGubR;2!CKL%|w^M{FSNGLzq zK2Id=`_}NYWWJkpN@C}6W3oVVQRGG(^7G8Aee}@ev}{Lp z!uuQ~ymrlgu9r^0Z%ahxx4Wk$|D`H0`v${GG(8A2&|V_s&o-Fa$~lPUP7(l;sbhUtkn&Hgao|aGgTK+W-9oa8(aNU(ntw+m00nx7c_Sf@ zWXBMIJ97Ic3*=vXzDy)Un2YZ>C(CyiD+{)%r*n9Qr-?Ly{JBa}luC%EsWOp~M^q#^ zKsH$E%+_T62xu^ESx_>9a=AdWWv02+RTjx>i%SCb7M?W(psQDq(dm1BL{!h^X8B1W zp*KWa`f>i?Vkp$6FCi1mXM2mbcgSx+at+|pEU1;UjGO?JaUZcDleHXbL@e;%O7V+k z?E9S2HjyzpsH(+EbpxTNhV%pm?GakcVrq{zA;H2!X+>gu6X-aXhBQ^VY3>gwktW<} zc)kkqQ}~aqL!Yk@lei&TN>#S9ku;$X`?Te_jK zeaizHjt_?ao56&k8#zjx#7p=6`33|2Z@FWV(zkKwm&*%E?{{K(H|L(UTo9?gDnNDH zfSz3&5}k*ZqzwC7#87PGltcp}1g$5jb9(llB|4DQH;3j6k!7EUCQ`WMlt zEv$kfNtg`?QZIwZrH1o$BuyqRodSFmdeIy}2II|^_}>&dg5$sE;iql}NUN3ycI9TzuUqkyKN(FP zO%as*=nQ&`jCgc1Z|?1HfUQ&USZoi`b{hL?L}zpsLRR2(6G>LJii|v#uspQ5;g25f z-p4g8@D|L&0~VRg@xU)+=DO+$6_9>;ejsPmxz6sJt@j1-v|5aphNW?|DO3{RZYbTX zc)p}Bd!E3^>y4KfOx^q67mL-<*HBES&)GUfp*Zo;ZUcJ!ba{{S&dTNhOnca264{v0SwLTYQ zL2Y^aFh04nHU`Q!C3@Vx@fZ;OfM^(ad9cR1{s})c?oLcAW(WDy+6rt$^pb$BZvrhc z#_3N8c5p3{VM$V7g^xfP(ngdM0cvbw1)P_=9-vq*vmnXIa2t=)kd+C93%s)kwET}S zutEwVp^3=IS-4Y7@4jq1s~h>o=zcyxUDHke(ql;C^>QJ=C0(KPEyIk*O>;i887?Q#3If2QO{gts9mt7_t)Y-0HR zm$4uQk}iVwTT(uXiOIAvmxyqlhMFNdFe6@N3NXTosxb z+jMZ9a&B0o$$7dHLq<&4=eGQCl=64PPR!IhTYyrm9kbr|&1%Fr^>6I_R`gXb{X!r( z0R1RWM@=KlUg?9HT-on6!w^k>dgY-*unvz(^lojT)?+*1S33$M z=ne(nb@jRkO?-#MkEAx0pmv!0q)jW0<*_g%mq@ zb=b+96K(UQP$|Eq@@Q>9EX(L=+b48-9}chy-w+V5RIOls?xO#tLnLGvTYf)053feC z7qIc|agz`$NdC8n0P|S}w3wu+g178%DpZHnSW#vYjIhMAIG$$By#wo3v{MOgZ}~(H z#{JxG5On`a3B(&Jlgi8n%C6WWF#`+o+t`a)ATQ`Dwf2+7RJux#-%rcMO4)Uyy2I6g zU!(<;C~(az0u;;xCbN%^jX6hUI(4Sr!|}co>@c`cOwEcnoiXI570afXSsrR`+QFrVE3MI$$TyAcLf zq*K+LKR&l%?*rEJUf{3}0h#{my5HO!Syg;g(-guS3a+%0K zb4K!JPJVsy{K;_NDO|SNVYPgmh$@r7dU)PGfhXLBdJ5X$>9B0aYw}J0to3ZQN-Vq@ zw&=NmR+GPN)Q$e(E?e&61M*GaN^~> z1$2Xz8rU$`X<>0=fklNDYZr&2rAv(a>6hg#?`c81c;q;+)D3#&PD3Xud~T-xOj4X)H=Q6*Sg^6ddW-18!9AnV4tyszpTn#@APFfGJ>J&s zQY%rNXh3c4tr#xp&i2ekB-W^%-mYjC_8w;C8Y{)r{~K(J)oTPbUg>pt#us8oxM~tI z0td|VsM>U2XeLMhP%`>6)2d`c0E=T#V6A-s2ZQ&64c3kGz3SAJV$D`tT)1c#{PnTp=$SHy^e6AtCBXbFI%m@zx zNGJCM3_)J~eLI>~)t*Ry`{5dMSNfW^!`E*Knq{TH4;dGGV)Wi>Ch)YkKGMO^Up4~;T$YYZ2a4&EF!s%fC@z1$M zL=JwWo%R_OWe6X) z#7eyA4B%XAKOvpHg$fGC?u)pljkwm9#aIO5FN2?|R#M*#yFfx>Y3Go>k>7tm;^PKL zpGm~qXs8-fNKASFkAjaMauG?lX;cMJ^ zg#5L6Sjfjd44g#u-U+LuyC0rDXM{H7`FsYyyruM$f%P_L zf!#*d4qtSj)F*xuur`_xY%yf_Az0HM+^C}jzkt02Hb?6sM|pD4k$e3UsvX`GFVl}c z@q%hI*Rjgag0>8MdE-~3Xcxj=WpGnB-eFD5X_`Y0eKWv!CXhv4E2 zrM5-SSD#RILbJ5h>~ml~I0`@tS3U{sMv?Kx@i`pRT%UNjI_9hDhWvQ;qt`+O`y9xW zgIoC4p;)IVoP7oF*Yg5q|Kj4b-;ul1(siU-)uzc0s@B{%!4c?nOD8gPaI*GLkhh{xiU?W|u%%8w~9Z)&7R6Kx!)#r^E3@YL+41wc-!$ zAMY36{0!GGR@B}iP@V`{z}vXP2{^x2mgzJw{8hxU%64wi$HC6>1vztl1!KB@jN49q zBRc+cvqX#jjuZWQs8~p&%gL)OTV6$zcE`UHgMZ zm26q&K8F?c^+0(*V8k`B3+|6V{)8}k!h1^-zcAPIz^En9qEVV9!hK^ymM@dj=6=(J zjI0+_I;4KIuOcA7nZiYqHg%@9fEVFQ(w5Co!|7$ ziS0b)^Nr3P2-p~*)=dWb?Q1L0+*luN$c2wDDlxn;0V}gsBH5cAh)JECb0C6?&>jxh zkI&3*a(C8=uv0;9J(@PpHIV4xK5`ZouC%2g5Auw>HH69aTyNV>?c6F!7A`&%F#9Q4 z7!ij;&1MhV@gq+l>6^w#d`*X4n%c9|r5IXOxr(N?41K*{Lh0Djd;55_IXble$MX^DNRGVpEWIq4F7A_665EQd5V1`dpBuIqZyHUv57-ne{J#gyt5KghPw%RSasgtZt z(o)DMT9uP4vCuD&ggd^2c#8R`WN^Lf!gxCuZ?4Imm*E$6Gd$#<5l^>urxe8I#C}~V z;0C79D<85t#wpjtrGGVzz9}?YDbN4<#X%n;0L8UWw{RtvwI`o(|7HDFS7cUDIr37NhoF$|xDaJu&fVvh9r!1g24iw1 zy##!Yglm%P04$j65iA9V4A8TbwAU%yxA`5p)5&>?M9&O@g=?4GjEnx zIdZa1Ia{`HVLpt&mMVV_sl8=IQ^_mRdYBYNBir)dHvo*$R{IM(Ds^J8wb~D%LXiuxj!l3G|Hm}g@N;Qyu`eLJpWVLcqW_!Oj?Jw#d zAiYqZ%jZfxPgpOc;IP5V_V*)h{?>?BcF^QhQf2_?EgLaek>g3tvG|lW{7k1n8%}%V zb*sd}_PSN3pn^HFJp!s6&ik2rySns?z$<+q1Or^b=TYB{~YwJ<1Rn%T3uqp`WczIW7qw8X;PLqRO)n$*d2e3-f$kRA8w+H@ z1P672tKoc+WuxR(6~@v@#myG^Pln@ab6QRXv)2B!c$-y<^#CWNN4#BlJYd0Ogq4<1 zWdhmo1P+rtKco+K;3WtyN|TV7HsliPZNhBi!}b}OMIEx)G~PKSyTp~9IFe?9%i*A* z*JpfQ;-x=zg*s9YuE64$wx+3z!$zKYXxb6gVsU4 zQb;nP_aGZMxY_T;Q80e4uB9L`YXnFnuK) z;6r%uX?db1T}6_z{T;|qiT!cR{7`jq^(xoRQ?U-u9o!r2lsBF-`K(TLW>PM4zV$^qt+(;HD?`8QT&xJHzL!%~fHJ~1 zJwwO+z5&N4&l>0uetXvWs3?IwLg+BGyLkDKsF3gCoXLNKJwK{9ru~io9>F7`Hp{9a zrW7H&HyfEqQ9j&|y4rfS0ErEfSf=%>;~l1$#wCW01fQNTpeQZ#TF1f>DG%dCqK#wf z2!b1Mgb?F)-$Fb$Co8a0v!DzR4fi$hib(3vuPt69w<49Sfnw4V z)kI}6Zi7NHTxttcxsU_epl?Z`Ncr6T2ig?Hm7mT?&8`(5RL_g|6KzT*)3{tfTf?!M zKO6H9N{iYO{N(GjS3F)?rUoN!gq!jZg2N7{6V)y{GG$s}MjNVDD4U6M^AKDv1Y`k4 zej>|luy+|E=Hb(dmobqx&{a-HBLwlRk5f>D!~KJDi6X6r)UCW;N3ehK9&{_zXk8H` z4`?MCoPYq$lCSpHlhnq8UF=vqtriwyC zLFx=;GUcZ3fab;w28fWHt4;nE?FSW=!hlBl-nlM!@%fUvn0SO^;gjV@?Lek$E-76S5ZpunGqkX0S$hG=GTO>kxiq7n6(LL!`sOR3YejT|+RilJLJ9 zSA9-Wd0z_P>N3oUAxp;5Bk>A(2nEo$6Wd`M1cC*i<07vaUQ&;bXzD|_yZ&uiD79A2-(Y)yCtT$I%?TO1aD6Xu1jFTKU zH=gD`?6^nms)h7RLZ5r{Ih{~mbym4~Ft!pC0x6catCAFRh{$6sh$vr6wLT+YkcHQ^ zLkUL{vVG6e?+K-r`s966cIR9IRCC$&Aa50FCdxVE_+B*f+U*Qp)Q?jZjM>4B_I&i{ zrlwmxcq(uyuKh{C^{6Kl@95bYc3TTQ-|7(rd$)oHpCEr_I=Nkv5eVs2Y$SN(h?;pHxeZPXUYwWxBaOxP+Zkw$iXXT~#@iA|wJ(B=5@V#1N|`^(RDYgl z_Gd=X$P@hf98#v03uJTqZ-7qH3dMM`;=v%=fPqcQN=3iMAKZ6937M}ujtRKk;wmM| z6v(a2mOgONYvf|$zQ5GsFb+(~7#1j45vhIHV9k2QYQGdSnGCm;>$oBOaCU^!4Q#pP zusKN#a?C$U){3LmQqMR)G*@DJQ!*?HqHn7r5lgb@$`a4eENY+pwDLYEj}WjJ6<%pk z&51!6(rVGLhU5L{$H;3jVC&_2A>pu;W5T!~%&foTHNc_g_xLfPukdRP{c;{IAw|Jv ztgA-TD+c2artm>?TLDw%#G?fw*ETJvsX^_0r?BWPRw)!AZMu$h9Ic}|eNr?I>_HZm zhFsjEfdjAz_Uh>4cdl4V;QMJau~0T5Zv5K6a};UD28I)SI9Tyl^rO;xY0q<8`-$7R zN`XpXq~G>7;sAo$iRlYsF|_hbyaSWkW&#iUTDqRlt$kwaY*VHOeQvJk=r(ON#to!N z2ss)L1T{+xL!8*aG!l70f3AHB;XPo3rK0SW#e&Cj0q^QAwvg#+ZcXZX%Kl+o=PkDY za;i}kGGFla&zV*z+cF55SX3!)L;ve4$3Vkb$FI{d(#FUdrao*K? z<4B9Qv7&0QJNbX0*L%cxl-nFRudU-IP`Y6D+i94q10Wo?+TNL%L%)CZ$p?FnT`6Kt z@@y@9H6ePi850s|z~pHEMg_~nG@RU)w9Tx;bP`Z5^5k4_64`$^bP7*q%o-DEeL0xR zD&{v6m~^gI{~8f%K&1Kr?ucKAP-N_bKPqc`&Lg%)eWHX$aHW+?%jKUvsLt%Ssd#t} zBJZ9fm+OoJGL7dw7w;|SB@rVZ)rKQi3z)g|V`1)74;*OQZp?&KLNMN95bSec2oanJ z*v1diAXM76q*7m(igXR%Je;&m#!yO9?{*+4UBGkiD`P>|m*l)=EfHwr$AS^X^X0wX z({k`Mgh#Xs00kIz=YE;@K2x3H-3iO*Pnumm)Z$M@Ql$&4GSV_cGT=%XN7mo$1B9I?9D+g1Nb^R%Jm_IU;FC7f_HfBe(v zjKpLsmN(gm;rM??$8IOhw7=xmzyEZ*CXc^x^Wu#55SBid6Ryy0#LUp0MX~m!!2X$K z({GiBI`eN+Jq+<8GHBc4wp|BI#QDs&cw##}DN77tPrdFxA?x*jASTolN?ZP=d)#_3 zGW%0JObP6hfhC4{itn~?!yfe<&g0Uz7-U1bK_}#Yhlr5*%!;4coIN4p?JFp1(e@B> zWQ-_h)pRw3^3~Xje+)7<5N!IqvF#`9Vr|DBMjDf`ySlw*yDD-@N2lLCAOl8Y(z|bO&WuH*t_)2yCtr36=eg77CHFt_Q zq*xjVkoSy2OZlYpb5trb5*i^KX>vs>xxKUHtgmjkIpi0K@j#HK&U%*~%GsnRjM3?o zG|-*P#T4?hKXa3bu72@>Py-uC)m*!)id^i|&iMOtp(3g#e04r*z8m;Wk}%foLr$O& zBMMjWb$TGNlJDB;_4dlV-d@8A#l*%Gph_@1f|y&HQ^)-bPVuH`%AqmoBuGr`mTz?d zf7k76zx!=W(5$*9jcdq4hM?w5*qzyj1{!k0E_@7Cu#si~{#^r;r?5 zIk|5iTdw@On#S^JZ?m%r4B?!J)Y_2r%jqE!;d2F|ffQ=&`1dLTpGaRiTY2~50zEyg zX9W0qw|}q@`pgR*){cAfgf?R#wuKorz#h4%Wm zHzCw5M0T!Nnl=|J0}<(hHWHYdh0Z<5f7h=(Mz0SX20mj!W8+ZuTUAK?YrmoQdOq+5 zrk?-zMzcL|>04k5S)x56QKu;5SxcMk-22=4Cg z?nS|DzV1G!&zbI-o4J~qtNc>zs@hg-ul2sq|9OZPk4pdR>;L$lNUQ{)&-zfMQ}XE_ zFa4MI2e;*l0vjYExq24=^XLBO#^2w*WDymOJ;X1L|JNJXTRdNg-1enq%m3W3|9rn8 z%G(bJ^2*=eHg?mS{Ob*LiGdC5E$r*+i2vK+{rzM9|7rN^)c+qk4Fq5v04Gpj&?w6R zaDs7Q4v$-oQ{H&Y*Z-Xg9*;pi0xPc0^H}{1kMt$7!KtUm5`8V3PQM-ML}|}gj<7E?QWtF~w1n4xl$DBPgdv{Qe5AJJ=#~IIf-0Ej9 z7=A}KkGP)XM(X_fxaNOHCw}h~dR)#>>#LyiYa&d|s^FYti+1S^mO&wlW+SHGmuNu0 zg)`S}v+yec=l=RA6&#C`DlE#}+?PD>vMUetXu&~_W@EY~SO64j=@tvBy6_AlR_=DIJS5XFt0658|`bL#S43@~2; zE%8x3*QF0LdY(4*bBxWvZ{b1s`Qal0m#!%#TzQA91r3i~LO>)yRA;zE69p@7s9zqG zw~mn&ej4MP(HDm`#c6q3>jh6s*Vxg~T#EXAxE$y<{nBCa3l*(H^k6)njMtXUyMG>` zyh$@m|5@z17EHqAoy+tU({xx%B)|0`%u=I#-Qtyq3{21ASPhm+^fwn#PT-;rARvm` zFC;pmSkE`4tC#A_*~K%bQbziVcJ_`w%bCC4Ggc3CBa}%zkAQvpO7F8XXCFdK9wqxttr;a~k5*P^nY2!Ko32JO!V9 zW@lTg=|w}mZa5%s`4y4GLLxUqPw=@h?MvnE8lIx|kU9S(zYiuB9fSDO} z1Fs~S2cN5Le~ciBUDMCZ;Z={`5!a(UOcL(!dq-+6vc5!aEWumDO9oOvvmoq#)1bsX z3J~*cibU*Vawf7W5_NrUspR!nPdg_*=8yi8x=-c1q3@IFd>*}6i!^~M5qC}KLQDFB zGmr?Zj1Ri0M$F7AE^pz}j$U_iftY2Enf{V{*je$>^oF2XOpv+epvjT|l?aS^2)o%t zrVmsSv0lhh_9Y6!?rK(Njl~5%Ut7^sbe^0XZ|0!rT$RvE)jSZd*Cxu%5cRyzDrK&T zXG@|1z4+u{S?Jjj|mqg3uS8ngcJ^B-wv1WR$neiY4M=Hs0G?c+MZS@C& zhJ>Q;ATH{n#j}S1+bMw)(R-&RkuHDr>wNdFiUSnIAvYYkOZsV~Q&ScwUdbjAzyU>iRU_|F- zHz^5AYUnv9Xc&0kp59GRJkP-M&EdWD7go^I&?}Rt_RgAs3DAIz+{l4U zl(iOZq+N65p6X4U68AXpb>dip@hRtm=>rUWq-o&ND(~JMf4a$e^wawoY6Z)bIzu|a zqXEW&>-HIYv0=(K|!VX=eB zc-#W<8FfT~7-?aTyP#Mc6-poSM}_+6nKK`Y;im4(Ht5YKK)i3>xouMeo{I&v07{0ks2)FSCe+OT65Kc?X7V-^(F9ZuCnKvJ(^vlnmtgT z%UOqpizxoxKZjcGX{KR?_hTJdpPK<`yFWW9vD%R$yOkvmP-(e(Tx}6F2~d=3(KxP6 zCCUw?>D8K+CZ(6$ZK}w&3pq*XWrRQu%3IzZ+3#p95!;Pzmu7x2(05&`UG{A1xHIb9 zE_GV(vPjOa%f~ooA9RfPP$zUe3xP%pZ@#*n++#+($JScW27 zKzkSi&ntvrmGHtE+()?q*W*`fw5n4Rl~Ua*yj5dR>({$9m)u_bhpSNZ9+K_R4I*}l zgM6S84yjkFjpC+jz&5^=uqUvELd#W0n)Nhc=x!7;T18m>wWVc8^2@H5-2D5F#D_ zG}bXPp3#i#CPbdMb0>Ja1iQw)8!iZOH@I{f6~gqCF^47Nagx}!7$()CgWzh>N`|Gr zr3low64Fw#nz4%&q@F$jEI?ClyrNZp$VY$p2Xo+VYy2XAld}m8BA(Q0P6WN%G5BfZ zG@-yP>j4e$I9^{7DnY$vWCa>LeqC>#2ma4Ve+~S|7{sz0)bc;W@cJhjPe#tQs}HJ& z&c*Ek;Lc;KmOGH{>h&FL#1;PpP56Zn<_ff%+@o5%)ZD@$uJe}l4eg8yFDG5QX_ZCz zbd6WHEHehyp8Lilwq231Hq_yJG#twl(EbN|o-`*?N09B=ysCY)(dNtt!6P9j1Tnt} ze(@8hI~*yi+YI`#Fv`%-r-h`Bu^WQ@M&RgUC@idg%@O%kT=5MQOB!E=JT zL|lHRbXcJf_OjyUd8}NmmGPf|TLk$oyjo)(?;${XeO+P1R^djl1&;PmMBj5Z00c07 z-7yEKEYges}57n)*dP(%^98lTyO@m+X?Hx%Uy*vu4&h6TaV z8MGa*c#g%q^}e2s+Or71=}{anU*54fH24WH39qfkMB-h073vABl$brdq}XZm$8VJfVPKxi5*=m-Z>h zwJ1jF5KMBSqkY5Mh25o6@shz&z|l7_<`j+pX0*T-vmY?GM#*JSGR%N)1hJ%naU{_{ z0+QuT_qR8l`HK{w{x}92P8-by^k83f6TeCc$iqgZ!bLEL^<Nh>rOrsnKll>q(e*@5i{FGo&ARj3d)E~09im} zO*7Z{veI5P{M+P>4d8vR$&=8HnU~aqfxw2juX=G!3N#nXm?OBFe)uLM1p!0Aky$*& z1R-YaBUN*zQ`ruP9@*v@N5~LxpFa zK`68)zzIx9|0J~&Bem0*?=P^MM2_-?vY;R}UXxLgtXUsdB)*Fs}ww%ff_+s$OoIH0Uj{UpN695#bl%`DG2Clnk-;G)B z3)_Fo(c*Z5U#^g{kr2|lDMTS{+r=W9%p7nJygpu%j%kLRS*$n^^IP)ZFlS+TW*~n&@sivsj*z}157)mMiObI0`70l2w#>u zw!_^Onq1_48txg=Dd5ZpF4JkKOzT<6Rkve#pRLz@aw>O7zQx;{c4|`zkuvZquuwWX zX1BI?6iPR+UGP19=lQGT>-tnw`UkOr9M=(B)#HS!^A`}uJ0KGh48w?8OZAnz5pRwk zq$uPLS?kR-pH920y6d#?Q8L}Ozb7Bd&UA}8Sz+&3NV}n6i&Z*yL03M~<~maZn!`TP zLJzyfcG)2a4KbaLrIra>@oqB&5cBJ%ppGt}4w6RS{7C=vu1lbST|6yE@^bfJ>flPl zAkXtQhy26`0>yfp**F&j0+Qp;k{JnC4rf(Zf_a_YsLsdJp5V0i{(mH&#Key})hH%n z@rotFzwG+T0J>vZMjtouRosaWpGF?i#{VwD6N*<3j<6l(iu7 zZS&Q%j-;G;vL}L=XKp`9`N#Phth2()(kAl!*Ryvc8>w8BHU1NP=02pKOa1>$EaPSQ z^9wCiQCj=qijI0#?|jfX!w|&^{8AqTW1}|!$J^vOo>Z_xn}aI(#CkCmM&y(Bv!hi6 z;3Qph8q!CVu+M3KNBlNWhEd35o--45#rHBQsj-?%s@8kAMcF#cEU=N&OdmY~I0u~D zjUZ_^y_fxdf`*6#oasBI9goymjL=b zfXZ6K=zE53ir}!1Iev+KoYe}}@^?ld#s}HZqp+B=XY9sVF0K&Ox3Vg&B=bt&H+~Az zD3t%R{;3SusiEQw=+FBxJ;#pZ5!5}iQug^Ju#5AaPFh;P9kR3SjM%i=9Zu&n-a<@s z5rihxX(fg>mg4tI2_0Wq^xL)ApUF{%>IQELBDm)(N1^=#xv%y_WFr&bFc zI^)-=^g-in6E)WsKvm0#vQ79gFNYu-* zA{M*$*P#bXb|T7)0EtgV3kXp{A$$3mP4z%|5kWI3-8&yTf^N*&C9-UW_CZ_!Tk|RD z@AD6Y==gwG-+JknUdP9LZ^*T$L+j(c70eYOApa%^MlSV9t|~{oMP{V6ZClOygfEn! zxy4#xw2=oRq?aOSR+b~_E(_Q?#aAFjrXtp&9$Aew=z(QI$6>ktjBdvM0ssft8lp3E z@i@~`xQ91;x$T|H-jJLZUO2B_4g16Wxj3V-YPR2$=A{@+-U(Xs3nGMVLU&+a2F-+{ z=a0A?KIoo5TTBi_huF13m?~VB?%RMq#a-&yRBg~wAVkB4|(uVS+Rmx5K zqg*4-el<7H1swJM)hOkignm5iV0;a(d;8B)+WmX%_HN2Vgy`vwHwl2?g{%8JOAV1#j@+(Jjl5iY3U68taViD4t{I(fq^Fv?Wh>a4AKy|hA-TBrBid|-089ER;NMW^~HRsms zi7jJI(vU5YqA~SF z+-IXs!D25=?GrirFU~$8px(F&M+rkxC?^Y)7}LO_L`QfOWnt6Nf}S_HQn3m+ffmRc zWlsm(*7OdC;gs4!@4HHZ+Jt|4!XJuLo?708#i}P?*tt!>A=O#`MjJbS4THh6t|uzm z7f4!gMIr3)wdSq0C-c@Vk&(h}CzkNJ)T#X{fEEVL_3-mcIZf<}-1IHSW)4v{Rm_rq zrx1%#x0#n~ky6l+z{RP*JKI2ee|;iM35U!D``zn;fayH8kj0miw~57j^w9wkkr+Qy zC;&!0hzI)JrE@15waFNCs7&BP_@XFGm7>|Ab?GO{FMwHZifH$WYxwDER#6A(r; z+Oo7SexCUC<*rBsYHA~xhd+qfq2nqbT(0bEyZI2&$ksM{%Ru*L0}V|RYS8aY2Ew2D;zdfhkVxr}i1<&6{KN1Q?1>T*a8u1H+~`I6G`@V>s#P%A&AbtywbM(;(5; z<6;G0*C#FJ5X9YJFxm-eD^Y_2D;sK%y6+1I=V=wAt43!)RDP|#_4c2uVd&5!8vlYQ zI50E=jO?G30Pr9_$e|En8^gIwYYLN35;K-7I{^mrHQZ7w6|8zc9OQv8U~i4Zt=SdDXL zX3Fx1n^r#UA4Lw#dbGC97G(wPr@(G6D$&<}0W3x0QE(`8K9jiPlOA3NCWi?U+DyV8 zsC&sEB3dhMtzk)VafMk4g)EHB-xO5yN1sOAeY-X!?UDrWiN(u_Z>+evq=pARA!u-O zBj3KLP*HA6(RK)krz=OrJ|g}0_jeBmOq`SIN?6;G`No3WQiO#7)!D1Cnx&G`Rmp?2 zOLXUEgzM*C4XRk1JXXhO3rYeL1^k38)JSuY%H4Sf7kheD^f z@U&JHR8sUX`kTAw0d@jDaaA0w7M^GOUEm@(G57@qohcE^*6D;VsCl+<1N{)@0IUB| zRi9O1w!*enn5g+;S$==M+3fqC-!!lGXPUO7YNhG2Y}=UT?k2IgHr1a-P`=As9xQyp+$(=zHLCHYdAE4QEAps2C1<-7Qr1c>T8n9SMMKZssD9*_Vzwj6k`WR!A94_?af6Lf19EU3tNGHQhb;WyiXp{+4qCgoTNa!WptW}yfy8_5<9xN^!rzzl&QOI@g zGweR~8B~1Zk4($jE`h`_2)gm2bQwI917Yw(;iVYq&o!3l(SN z>GW6OcMbUV)p)+ITSJ*8@u=6VlI*tuj9=B*kA6<#)tDMa`dwea%ec8r>;=8q4q(PO zo89OSch!pB-$Rhmx@O2sDhj(i)1W0@7!8qzpmHmN5=e z0SYDa{H0X@0;|348~_`>5=h$?{cQtxJyG!?*t=YAZ8b-+y-glM)>%ka5gvCh=^Ma$ z6O4ER)l7sg_f!^|C44>WdqLw(ndsnr0m;ODO{+`|_xN@-u2ZSx9aRg}<>PfY9j)(# z(5zV^)5rML;`VneY9&OkMH9u8S2HIHWN6!iq6Aq^4L9}1YvDG?E*QDSIpN_DQSfy? z(Uk1Fote47%+;$QYmKZX!pgG*iq%yqz2F%O=#;{HRiKRS2;UJ=4?Gi+qW8uH-;+bT ze;b@IiHeQbZ#&jQ2Wc+4Oi9)waQ&;519i|>>)E-&6qLamq};))F5iKd-hL9c7e)_M zdYRc5o*4*=`H0MDdrw`;hqis3gt|4Td;#{czku~pDj0nw^mSE9l8zM+p^t&x`8#-$ zc`RA@3-pvGmXqIgu#_-L0qt&kSYVnt_bzu}=@M+*8?~Md14J(2oC7yvzYJ~R{$u_@ zc5y}|5x=PF8ua=sYZ-9@v0(Y46nX5Ynzz0J*6dh(PSAX#m1A(kp&uXk5xs*|a8>2Z z{3Iw{aDVbwr#q)9r`7DQqb57pFM$oME0-|a7$~V+8|mgIoh3$BDN0>VB5z{wZ4kW& zK}e@$PfIQpr(zwWQa+iThp>Bk69MyA#Ii}PKHxHpRt%Yw6!O3cGi|#Y++Xd7=AZhH zMhnA9Ohyt>;Vi|lfo2W;Xi?RkMx*Tv@25%etRE*dvsvQKuee%ei?qvs?R(Kve@vQC zE z76oh@Y=ZW^$=e~AzpgQ@=k+@73rvbm5I6-<)PAIp*PE;oSw6aj6tzM&uJ{eAY4^ZV z$9Cl@U%{k_pV@_5S@K8^7S2Py zL}8he9I`g!cqFZWOPs|M-L+=9ve_W&t-)7RV_3&OdN%;EcqHAljv0rM2rQh}uB-W_ zmRy4&CG@vmk~TFZ?8~W)^=&S~OdSFrG48H|!J9x;B)yADh-o4K9I?~VCLz1?Qhp-- z()E2jU04*}(@FStHw}MzyoZrM;hd>>15;(vVCl8TztS|pc`p!P5072Ss-~J4myu-bG8tz+z{hGF& zDmxe$l~)U}E!rn3_(8gH;r1dyM7BKRMPQiFzqkVLzzd3;P9IEh?OVrDHh`1ckE+2g zqQvA1@7r15L__P?W9PAYua;-+Tiz>yCvb0X5UPf&aA~WrUA$u5DeBJ=aJ83@4F)(4dsG*s_1Z< z^B@LVWwWHm7Qal`$!-In2<^rl=q8J;Z9$?drTdIdaQPJ;v|+U%UpDW{Cga@LV1>|lU9N@rivCKu6j>CCqjBW-^~;EqQkASQKiXT< zzHVt4>$9m#7z?14D3;qVF()8&ttr)l_MYEnwnl4m`DBA3MY+Yw111xZ1rg@A5PS`Y z`=VCG4Y`aoka)E}db;n%3>|-!0V~8^gK)n#LdKxU+^E5?{FC;dZM+IIDG-1KoQz+( zNqOFx^4z-}<;Pxc5g33Uy*;U9`#w8*br#VXY zZ%I?lSvHtwXe~(qLMy(L2EySvEFj>axlROakHQa-$HFd4>Y6fZyPbRe(bC17q)b`> zx|PTQJ#zhsF_gp?lQEnwmvJ<*72sP`BR+KvxTbA65E_zf*-2t*=)9E0ObUYk%#WF% zRWK#=sOix{erEQJ0DN&Q$DaH;?-CX7HruI4&K_STXm;_!0Hz)v{ndVprP`b8h3`GU zac%9Zf!q`?3@y268q%+igx@+6%`{!@&u7@Ky7&T4O*&<{;)2y*Jmd%6lIA{JKjP{F zN0FmZtDZB`r_p_Gsx~=f#2kLmp_|~5gC)724P&xu$yFkUC45OqCg3G8EmyLn?9=1y zO1XG5G)%R1_fdVXIRp|d=n?Mm9!_rp-pg!T_Ca`+sAzWA?wW<^AFzd3@qJy9&YS2I zI50W9r)vTO4p7=PeWy%yt>V$ray=T8J!bzo>jfqS`^VS~k6O=JYQmY(_E&I6B%C$n zUgzpTNxZ8J9wV~N=i4CJ`EHu-bDh2A`jG zhwH&=VXJ}s1pK6=+Q!)-&b{uAGw>*DQ&9-Fe`h*9m|XC&nRtDNDjo~lTZxteu~(@o z#a$xaj>-_$5w0L38_T(*@oKCx#Oh%*Gl{>R{H!gjla2X&>(4t4>3x3V`$h$Y1f~_!?_-r+OSAb2!28R2#;!!h1v|#Ny`9oga;eJt zH;Oi!Ve$e1h*LK7UVoDp;jF*cY4R-cR}cTE0i_1)dgCg10*+$6@fz%EWJWk<{=^gM=l;RM@Oc$r-@gbE99$M3R@ zRn8|%U*;DE$4!wx&;2u==l&TY-9Ioo{1X^7#@hpsHyByk#8Rllk?7S+H2s4R3gYH} z14-c-t2%8;hAz^PL`rf$n2dX#zDWdRm8xYE18r12e5aw#Wk{h~V^p9L_PDe8Lf9>_ zP|8)i?)`1{mY33n`+^wDKt-ilt;Ywfo?m47Au1B;kbKDtQ; ze1S$jwVFpYpIV7>MuYQSpkXw%VuoxuKJykuUo%dyhkDs1(p0&Q4hVyj3IWmZQG?N- zMD+Z{bQSjDDrE%_iH^|AYqQ{rLv4Vo?pcg>V+Pn9{bs-?&-IAPJBN9&BeidsZ2qI73!$mg9Tk9x`wUgW z4g*rw=2I_L|7J5l_qG)Os+&}n6m;1IXj#r2^r>q&NZ)qM7^GmWtPoH~VhW{wN3?wq- z%IrJmS!ve`f@UwS=XR#8{td(^f&B)9^bGQNBS(Hy=L)3WAPfPH)q}^kvQ#}6&iQbj zf1Ye{IXn#+@73z#*@1hre%0p$0(7bSQrRuRZSgmnQ#yopO%w=uWgnMPIKFggHl!pM zqh=#ne7f6AB|;%FWf7sY9%ipxtp%EuqAyk^Py7c+sRR*l4b6RTz(Px4DnfikTKK5V zisWAJ^SXTbKaUoGtH%t}Yqk_H%wD@!htZo%+KpoDq#;1e_mSSTKfzE~;Pc|!O4u2e zOJ>s4?wKgU7u-~{4n!L9c$R5<{Fk^9BnULXwR44^73x1Kdblq>)SynM4zGRB!yd@e zf1;{L^or-H%T8MtL5h@XVL^)r!HE4q04Ag%QfDBe-NvB!#S(%}>x3{*8VSEc!>Zp+ z;ZxM?_6+ec!(c$-Kz#h~pI3|Z?x_*DhUguj9CH3cF9?+P0pdbk(9Cxod>x$wH2uR) z(cMQA-M{YSq^L2t!$}49O3>5#+Mx)c67=9&uu7wCkBF-+yD|2)Zy8SI1s2@-shX!iPk$Y*PS3Yi|>uF%x%*is1bG&ns8qvASJjJllE) zw;m6e1@97*G8h=R*f0UChhgQ);|sj}!$o`Kblw3mstg)?Hy(%mg-hP2Jiupc+A!OM zq70wvWuPSGG)f$6P3+CrBuC0i5`>`IBDELyrMCwsttO;~@BMYxjO1IHV@L0@H%LyB zy8LZ@JkxTn&7X^K&q8QaAdPmgr%3yg4NHIJ%asF#*6Qrs#*-Eu{JYul*Dq-9X6u)n zXVR;PqUZ#R<@=>zNK64sodPL@;*_zQ74MObIONZa=nrC^f5i?K>?)~i| z61I-kw{R@Qr_((011^D>6(KQ;wrHZuUM;!rPeP!rd`CA{w~OjBU_Jm?KINDSp_HGptZP4oaFa#9%FJf7Lr3 zV!PCa@tWckBScjhtS!@;22FTeUxCykFpl1~o$RJJan*ZUpC$Jj)>SiG**ieR~+)1o|zLM*|>o)x|2^)h58Vz6yV%J3t) ze_h5&X4Bhpvi*wAf0;z(w=EAOi|V>o3^DVM+?AD@bN1o0wtxv6&>Yu`h-kB-inlS- z%4pJk;GUV>vr`#ahDt0LKP0{EFkB6ZfwK1D#TDFbUr|)gT+&``#+kvpTPf^1`SifJ8qQP1G}6 zrkvA%(sAWypWrHuFE z!Wd)|8KvHxuH;O;3~Fgn#CaDd{6|aKm#JY9l5A%S?rRA!sS!;O#-q>|0V4vWM&#CD zj6#dSzOZF%pvNmZRbTsr@)$sZt4sPU+IO(8{j?FDWja4#^X-B zAm>A^NNIF`ihzzGD`=2*zB7B07h#vfxPHHHP?2D`tew0r&NF>V&btE zLQ&~BZS$GHhm##4S|DD^%P1b8EUeX5l}{>IVj-JrGi#HH24k7lRWbK|kS>iOE0ck5 ztE;kYD33CKBQ4yLv2~-84i~S2ZcplUAw*Wop4Ho9mALi~chyODZ7*r3;ds&%=n>3n zS)%){CAKMraX;jO{yOQ;isH@5)M@HkJ({QWy*wx93VWY-GLk$=4b z3Nk=a1P1)b<^0#X7|Z)iZETZS53&F24LY9Lp*66H1u#|r@0bX%6MkQ!0Ei*h9a-n% zp8=Bp$4-Gr70#UwGpTIznz@(RA+j6(<=Dcaw3Y7w) zM6ybC>OO4`CKp;x6`l2)h5nl>wE0b>>g6k^{mBnCsIOnYUT1te`XZhUCyS;^%87Dd;L0h8gIsdXo~{-_J?>X z?*@bx&TZ>IHivrFO`oOM+`9w$72`AxN;!cuefkvid}K8?3+gNf3w3t>6>`>(N&5E# zbJg(-O0c1}Vd`_{Q z4>-SPc(9SwT7ME=JdAzxd4f=QcUt|4+wZP!4#iH3m1F}@ z79dIrIBqylY&b@nMGg*#d>$D5E`U*Fl@wni3~V^OcsE&Q99ZMgJsyN$B>I&G0I_b! z74?sbC+hK__Xl=P(nYFHL$x!?zC`CIKDVp|F)xpF!nj0~4G9gH0>Ln1{@XThcK=S$ z7&Sr9*CRrJ>sBfv1#B`KuCC zNwl)bbs3B>R-$<|{1NMbqEAmgUph zW#rQV*4m=kEP&JA>}vT+MGTkCoEX3GO1Dew9vz@kF9eJtwDj({=#Xb5Uy!hdT^}w< zTg{XvR-A9?XQ_HwYBfw=#Pd$LH%=~1NoJ^O!@WZg%;>a1Ix``(My zGWxU##NX`YTkK!fS=#%!HtYMj^Ly0$$f^H@jrt)P5>SO=XiO$5&bb^@%Qc> zPPhN*D03>8U2f^ZuYsq7vc?}(CPVZf%Ejxhx3n;};=$42=Waup=?WH$Ts`!9A$K>9 zMrmviYkPFL8L~&C4nOjpO3-8|Hd)_zP%OR3X1OY18q|>Caya|Jg52x7KC?m8as3;- z$V?u|{$iDCzT6KNVD(f8-?7jI&P6AU)y#)Xn9jzNhVXONGNlX64~a~rse>7DuyFlp zzy0BC@V(LjOW6o84v4=P5)IfY18B@G#jW*@?R>SJu%P{ucl;YGeAy@SdCFGmzvvqG zI)JX3Z`p9<^SsvR@85ngS8aMdjnia4l~U_;yX&BR@h3liJumgAYFYVf59m~4S9F*< zwUF~z&Ep6V2avKeNv)4wJ=%$to3+KDG4W4ijZErlb+=M$72vt;dXzOHw8Ho|x@P8k z+VWmSD!J7lz}#6N=R*ODCpy8AeA2n9Q_>eL^xW}a71l7#DqzdcBD!oAYTSni)4|%<8UB9Em37uD0U;cAMNB;r(=18Y0^G(bG zH}{eo?$fn(HeiyV9Q4)Xclpn0-iRq<8pUy7WF1|5(<@Ps5ZU`td-}5@1ard%z;XoC zPjV0EGFDeQ7zJFgzDX(kSr6J<_B_rLe!PwQ;qbKKx;D&z45q0zGht7YNBfYLsa&}X zBxtk~wHnP4ReLGz#IgomJxwJVoc7dtYshuh-F*RUWgooUZt)%m;)-%RtfD z^pES?-kS^o3- zYXalTwfU=5b0D|EeNb0PX{(PKL}R$TNwc}ocmhVDIrGejstx)6_y{?^qQMiEKRv22 zp0OpeOA?PZ8^kWn)NRsLiS&kG$u6v-Z*H-D+`wc;H4_S%7@^ha-F>0Y%nFb-nT(pu zm9{-0EXX$$Jo4|t@IJTV=ev0wtyf+&Cpqrv)1}?r14HYWeh;iMU_@`=#+>*g3?KC4 z#^xU+jpmK$qeIbEw?3A(2=WUus!M}^CTLLqB50V6VGiJ@bD#N{44{@~^5-%sN2}5j zGu@>0SE6hpI5M^F52<1@Tdp}Cqh3px?e8s9kE}13f^}{*iwT4vA{yE=G;0ZJlOtT7EQITW&K|bkQ3D8z z=3l~#(nlU`UM)7WpL;6Q{XbuXL@I3$Q!qw8>CLYGC{_+_dAv_Gw_s>`Bz8U-r!$Y6 zX*_|^uCQlq*2;a&S)kE75LYf@SW>1-EgWw1fL4PF=yQ`mhtx%?`U7~cOfC@tZo_V_j=r%k%GHKButt!91N(G z$h_^3_00d26j#5?a<* zgz+Z3Ij0lO7`uisX3ACwOYQcjz2tf-T411&pyh_7^H6$!dH=e2 znr(c+LKl{&muJwO29;1&RuvI>_2%c7SIRFXMU>gxHq#u3d1Z!U<6<3S)8scvU*WxC z>4hGYW(O}fH#h4Yzc?PIC$}|g@Z@V+nwU`2Q&VWZ_xVOCOs`8ToWOYXBd{=&^s+N* zq&1cW<bNF^civ2ENWeJTGnV7d83vgg_CN^mWrnuiD0PBYKyW#L? zFifMZkQ8vC6EtR6Y8o3W&{K6@)sA!1F3e2>r00QU-EyeUtx7suI^TDxYyBo ze0E750L)I0l10~uScQP8?pN>4-H-IA{Z?NwVUd#zWO``iQ^Y*4 z4--yJ!nfTU&#QO5#3EB`<4=*bpbe^_b*ONDbSn9tVxbBL>Y>3RzzTceI(;|$kIL3v z59Yzgt+1^vVxMz7`q$1~FHcy`0kF7pv*`jOsyz39UfS+U|e&qMs?`-uzBA>$D*PWk^ zP2#*p{TP2p8qX9+CZ}^)L6red3n#6WSYcdjSXhTk00Y(q_lZZy5rTA!=hKX`?d)8BwxC6Iz&nZk>h}kx?xPp+GK@7Qy_P$wde!0~XRkxkpRUX6XU^bj1ZQ(x4qz#6@NQnhZ(g2#XE1v& zf~JO~-_gfx^|8nEerz&%eC6cFdqqhDI!Y}DeV~IQQmk^*g0nMh7Sl9BFfpQS7E!vd zM&BoZbVR`N1Xfo#2)~Y8?E3452&SZQElU&7$i*ooDnWnaZXg|zPOA;)W=7v)pp5|6 zs8wzCs+C<6-4F1mj7Vll#=r2wY?s_RH*u3{@mD`(67E6kStG0=#i+c{!3rGKmk48T8SbV@Kq(Xl+*O7*oiVRB9eQ7$ zKO3|9eTjf!PGVvp69kQiJe}qCM3O*GpFYzGja1XOGK=?=oM*arHPfF49)=fv>{MN)4>GBqR57Ya1X~N|CnvGFGKpjc&ybMQu!0~_Og07nD=^aG05qj;p8^k|L}###?v#bO%=_YcQ~Bs z4lnBKTSu*Rdjq_;KIFR;>e|INbNo}jV&=5rN{>QnvzKPyYLJz;FP@dK+nP?D&CR${ zx{ykTmdQA}F(blCTRTC;-dtn(&3h)_(rM$7Wp8~_7L4iMC6CMN4gzMa?Ob8U?FeR# z3^;w#3Pj0yv-fGI=bE)1k%>>C<*nD1Fw&1t_Xp+r^?Gl85Q-+PR~hsk;aBDyg}dho z^#x>83fZ^aEZlB1J8o(DnK1}TsF~J2I;Xm=HM(18M`S>eJdIMy)C0E9$=zOh`8mn7 zx-3aC-@a|FMzNY3_Bj^ym)T!8A+)cw-7x(_VN#)8Zt$K$n#Q4^7>8Y4XqoY%QduNm zlVId^Gyo2}uN{^scF?O9Z)`|b6GWk#QhF!++`mi8I_o$S82=11%#+HnnfaaHG@}2y z1%|o+9;BC2XI?1KIZv+7!aj~OT{{B<>|&CJPVEV`gAL!+>H2d-2oe^>M$p>2(&LNW zr1l&5Kwc8(9-rmhM3x89dBFSRPV;CH9o^ZF>rJ%Ccnho|P)ss2tT}A8Q;A#G78ox zBWWMhb6OsT5LlL22`T6}$G1#0`G!wZY$z1Ujeu~De|^|^#ogRnzTMut_Pd?Uw$?|J zy@Q$Qw5K~M*}K)8>-X7d7k^HdC1C93d}=kZB2ZQnb=)A<$x>c_IW;VJ&QyCcK7g*? zq}jX_;$}lpeCBCk|MCySixpZj``h@%)=&L{iB+R)pnr2J^v32!2;Mj+eABy|zufp9 zaQ6VYAI&$Jg~l-u{;q0#yBGVqHP>#!|3ko*&ktQ?F&Kzw!H;ZTy{qO2WxK`6-V2B zdE>4@8g~*TxCXZ%!5Wt!oeYTHGdz&)0M^I#4@&5hrO<%Bbi6d?8EDMrM@Mer6ipAr|J4oKd*05`V{E~(liHy+y(s`4usuglJ?lln-JpUak%Sg1 zJyS9TIb0}6@J7G!_x?`$^CJ*0yVNJ`(aY0KHuhMnK!S8O0sg>braW?*f3&ea54T7K z$2_CKQKq$f#Y6HzM9gT@x5m7d;a*W3CE%9|yVJV5iXvOj^3ECv=0ZHJCtEr)t>SrO zi8i6)JX*hSthpMMlC+&0P4k@fFqpO{jNH94ySy>Fdg+F6t}pO|kkhI7Y;NS?q(5*! zX~j7FYMP$qI9&YQfQRRKYp_Ye35p;UflhoGm#WYZ86rWd5H%Gixjf+OvPIS%qS0f4 z_vD>r<3_8Xy=Jh)5mO`)d}Pu2v1+lbA00Vd(JzSZo`dCnMVV>dJa9xIGxzHlGG||= zRn2q^BRyi8oNyIbtdeOlp1aJtHTTNWEh6|48C&I7<5ag7<=QB#uL-hx(8?+vdipB) zms;ED?e)9BWR5}DMRI4MU!FgH4B=Q*yz`S6eQ*hKrb`KZ7hpkCf9gn5_sTlVOIRR` z5oJp=!u8<5Yqq>8B~G2dd%d9D>%7Kd@?v+|V1D~L#=(C{jV9#da+SUC75qgAf?_aTVRYv*;-0oz~25qC) zys8nnqJS~M2!`0izP9;tLDUWNsNKV7WRfSrm|nIAgGiF=STibytJ&LLtZ$j|zA3@( zr7jJ7ccV6_n+`N(*YC!?rdwswNGI>0rRfF7*Tnn^59}A8HSWPVK)9!Rhu*p>-7&L* zKKs#23v+L##XludZ{LF?LApKF72Ul5;vMHqi)KC5J%^iW4b0~+e_*pxiHoG$sVE%U zqgtn2ctmeDMnppq**Im^NgXy_50fC9x`{xoOvm;z>1=IVr)4l3D`HVh;gJ7&_qEsL zlaeD*{oXCWV&^s^3acS1lHQ@6SIm$G^tDIBGX5(?@lX?0w4H`%!dtyO&ykoRaP@i?+5O z>2$fI2J=0eI#0_J66XR5mP5!itQR&;9T1Fb(V2%@w(BF}Z&;@|KWsXOh4)0I=hp!D zK;=`D2AVL%6HQhq;aE3enK?Q4xiTF(bBW+bmu*D}csZFebU`P<{-O?^09XVrnq?8nH?a<=AQZ-)C{efqPsB&G2%>0y9!DS9Rxvtn>v3NUtWd zv*55uguSW?RNAx}5n6QFZ6V`C*Esm~2x_p2&Iqp%BF^XLX2uDM5i_7JfUgdQL$s3h z=eJv~+iAML_xHAci7BGOoqs!~=7#G;^D}D5`qk6NKgMl0u6b5EGk3d==M_=cgZ$J( z&)~x)P!Q7;AmW3`Z8e)R*_PQ~X09%#n(szn&snJO7J&pJqOU6MJMf3rptp^)_=xN1 z@=qmYXi>9e_IgioMc=nmud1hY z_HhpQcn6nim>A5!_wa;pCJw)(Lc;9v!Y(|QnjHnj`EkvjvPP<;g9gn7ylI7I`2!)} z=+M8e`hZdMFxV-5%<&#xGrVMCcn}ZjY`x`W_FGjO!k#>U*#fht{O1iS&L0@24PP63 z0QT_(!AnM?$prE{6u+m`zdFYNykcS1CXlaA9zcFAz*B7bwaxGVLhv?5xx)_?O)uZw zjt)f>zJ163O1G?O1n`JBv4mROen(7YG#FaW@*k6LFvtPC(Kxi@KzSJ4+{Bq7U!M zkuD#Zc<3>j!Ygr`yE~Uf6Eh*xz2||u?Vky-{`lc8lP?iRM!JU8u(tP$1OLCu)IHU? z-?B?KkAGK*nQVf`hIq)Vqq^-Nvs&vGu(*nK1H#GjRoG2gkDG@QC1)L(^=alq%_HDa zVSx3)NSBCV#-mXPjz4RTn~;0|nGyqlXk{izFQKUXv$26ot$@`(mz3EXpCqhr7|7d^ zk4V_pc=#2>emCk+R0Mu%Dx!8~&%OJnZ4l6Y{UmY=DRu!8r|B6MoeU#@Y{J^TQN;&2 zsFO%c4Y`|F6K7>8H3L|>(XQR&bHed7q5?q*o$Tl)a91g0Ofx60O7t4A4<$wC4gUSX z7!U5Nn=?r5eQ%XRWTY2GPB`KE+G?QvpwI-a=92}F73&6>2m=)1m$%J&1H1%c>LkES z5?BaBSFBME*J*&r16ak3C)m?V>S6w-np2|>w5}Pnho)pa3(4fj*?K6$ez;03J{!Ye z{0{*3B9wZ4`DbjS%LIP?O_qD_G)Gv;Qbi!-C@Kl4Vm)yl{eNKFjR&JC!t+!E+a)*> zBh?GG6rHyPCqGz!zS1z^JU`t`|6m4~M+3v<=7Oe@IIswsZjBkW2pZsq<0tG@kJ-s} zqT(aO8nnfx_jfLqi)%Zf`;UrI3;&FaIFRv4N5*?q@zFUnO{3ED>|KVXJH?<3tYGc= z83o@OEg$;t+((%+F_AL;(yf$;uniUJnVf7u^Yng9{$F5nRH}S|RD=T$h@$ICGNULs;6aMHtOUGPj z&Fuk;@QSUP%O696)x6Webpw@nKuZ6`#)+<_;6((gCk;q ztJ)sWH$iXJzK-4shRX=wr{LY5j~7$$7cO>M^tGSoYv047gkymBgimowV9zj5-xCx+ z+}`K4*?j%evepwj0x|*5NIMFWf(VG1sEoI#3skgNdC>qBhJ3qKn`ETp%+~S{@{GW1 zj^(&S@gH9S2If_Y6+$WYUhuP3$Li|@%LweQ?o9^?4ryJHI}T})TGHA$kI5O|&l3gj zn~2P7pYh#2GGf@Q4&Wa(Aa5ZhkVQsD12fTe0^1uKJGn~qZO^Ehj3th}c;emKJBHaR zYncccpw>N2X9yY$xZmv7EqoR1;@qmT=;!%n5o2`aj-sKJ^FnYvO3@SeaZd7H;@C7q znTWUwQuf(iOMgcHk8mLz#;SphnLaKPGMLEGaiE+g@H1^SfbFfAt`Iy>^w$#sjh&F* zw|?i}nW8s|Qjz6s8gZI&q$gs}EAVP5*ra!$!^J;~+eSr=K z**bC>u)jbcy`~xH{!tgY(%noTLNmw_4;hBQysz7N><o-Uq_Bb`a9J+&hL zys0%7?g*q?mB#2_QR)LMJBPoC$xfO zU!)Zv6>$nJNZ5X z^+Ce~-xz@teGiP&_My>?lEWk$NzQ$$GMn=*qzg_vEx1&hfCVhYKc9teHxmomTNNo+ zfa#d@rAnVc3kcNo49k z0ndO5F_iDCc4LR6hg_4Sk0c;!@_r1u!xUh@%Gq2}a<#eHLG_A`qM$qsm>@u7z}pYn zmF!>LX?Y4_W)Ks#Bn^rpIld2VyN1I1ksUrmugssDFcQ~;O!b6RD2+X+G0^CYo%Bs2 zc$^VZpsj00!t_EFBK5uA5!4ab^!zMS{L@jRtC?+K9OIq4*~9R%K-$s!@7NX799fU( zuzvD5s^&=m87g!p#c$bO-{)!difXOwgae0-A8*o2I#o62_`Lh-yo-^mM)tOwEVvnN zVLf5zA#$1nQ1*PkCYakzMWSY&Hl|`wtSfK?e|UmT zE}#$?*6hm=4KX?Cv3&nGUHD0@B}lQk9{RA_g3gFp)mR@)8??=w6Zcm7w?)I@O|8i={B(E7-DKpe4-1SfooJ zw|y569sACb!k2ZdoR*!+_CCekB?(avhryQ(_rw|p>{_4J`p?t-z76{YPXlz z23BEP0D_j4MXTpv(H-e9WaNfZc^Tij8?oUv$&RBGd=OUmEN|Gd`0N#BozsTL11WW3 z&o{DTm}*uueFsmmg*Z3+7bR-*s)|;)pubp{@eIYp&Bv~mr`s_ocw%DdKo7k)wfz&Z zdLZ)k{#GIK`SvK6vzV)n%iHOP%Kp*EyMSa8Nmu=Por%WSz_>Y^1NT+j*&C7Z8nXGu`-OQtBSJXxpXt8$h_U&q@kJWHFaFhuuG_JSnAZ{laXE z74myG?vTuw5LUSrU731XiQ(~ZR5z|A`!^X{Z$fNWag8#9*c+MMsez zYZ5q+^5g98T!Fc^Io|q0oz+{JFY5wC22HoZft?!QP63s#HRd_T4mpqii)XO`cov37 z|F4U5QE7+`j`2QJ-WQ%2z~i`&$Kd|m?`s0{wF=zc+;t-LnDq!#j^4Gjuz?E*6o;33 z4*$?fU__p+qI$|QBrtwll%3jsh-6X^-nd_7wtQgqbi&D^AF z(btZC$fgeD^R?M<<;_8KlbJTwMVhtW^)|3YzyQ)toyq{SrGlzpvrjnGC2iR0cDdVo z8~uGj-_R-{I;5xlmh#wZLi$Op0LTn+OPlA}NvjL*JrP6y1T$`#1jHBqq6uW1ps!>#%1PmQfostnalxf*SfMYSBHyNE;KA~DBqbOLJHiP+$W$E+KDf-LzSn@IbVZs8K4b3%baFGal zW!DgRq2FCaiCn@Yov}uwqWHR5t+e`&=gCRhwrE5=eL;4ZvYh(y6?hcD(d<^YxL>R6 zUyl4D! z9cC2s#!Ct!eB0^em~NrrA8kLCefoybJ!;C$_oFxv5EC7GJ-HPVVH2`^)Y`|7@$)TH z)rhF5i21GJW_>ILp;R4}#2)wol0S=Q5?URJwS@9T@X@vg6gLOrF_H<0_)wInX4~tq zW<|OVnK~~6a6ZT-jRR9ZNDMsrZLP)1Pb@M48jAJyKRxduU7xC3A_FCFSfSX+b_JTn zu_XkHS3FkBNCQ-*LcUi`yZ+33_kPS3cKsSL_D|d2p)C zUeCc%k`YI7|Fy&Hbq?RLW|=+XgDoshdRI=DQ4iZr9bg4K_jlVN%88t5R~081kC=X# z?vWM*48r%HRl_jL5yKNEZsaDuq+T2@$11;SjHL0*pxrf{G(CRukGRDU_(RH|Yr3lP z%Oa4-A$)q}k(}2JuJrG%Y9Of%SsCyy8B6i|*#m*adb!bm`03&YirMOk-QU^Ji`#^z z2L#0S9!AUWeMGvApMTC!ydWt*2NGiOY{6J45h9jSE>YO}YguO zomfb^6(H0v6WRk@Srs5fVVo2gIBYHD?{}GN*E`gY=+p`VQ42q9ptM5}r0-J7+p_MDnxe~^j^-h9eyA`Jx|Jk=yO3x{FsY7fEL49vk1s#0K_=dbeykIXnT67cT z>@JRz2WihocoTv5TIu^jEpq}==|?)xp!YB-z9^mFV-6?p=56~WU< zrz_bo#(I1;+X=MvaL?@D3RE&6(UL^4=CLv{fJg3Jv{vzPnk@O(Iq=1Q_$BOiCO80McZ( zHRx8UlhLdme?}Xdk1_||D8wE!kAKk~8I~ZWP^!j#9}Nw<3J>DV$AKkl?aM+Lk??1m zbRPAjc#OOzepA&|)>`A-X95>QVw zmMi~|3Wq~Pl*?8P1&10lYpSY83Vi3PdBdc^ATz^Z^xLcR_2)M9S6D+KIumc+NbJVv zQpbG7MZw3AhrB8k3RPwn7eLnG)_BgA-_wKOUL%r~UCkHF zN?NGW^k1_NIX++{U5dRrxI9L1Qc#%3hrBpe2C)_TYp<;zqyaaG@D}7#c%7!3!9Ro0Ca3)IPWj3>MXWO-es31vM%{wbexaq zU)|A}AVL=SjkeyNs#OF(8a?#ybpa*^*%1eW2QAL>$UN_42k*3(gTy|F!4yGL>JBq8 zuyc*J&9L(WUU!?ptLK5<>L`)&+7L9|Feg#Fuv?RyzE`=Jg2OF_>t%q#A;6}-!EPh% zor^ni<}H--TxqfLPd7NYq~@31MX0U~JmAM0H2t87t9}qU?f4y$mzi7m(Ug);Is)dsAe>q_N zg(>Q4pZfZ5T7UW%t$+NI$xq-1`zJO3s~1>+4y!Ew-*Q6UzT|{d9q<;{0KdThPec6g zxRDtC7aRcqhV=f876^Tz1&r%-a{uLkt{2=O)W3N1--1TuU#`;IrXeQlfBFJICm-wO zB+2wxwEhWK07@dA7qsKcoVBL;zZ_uy!fdRsS~UDiQc2%`0$T=bsy~qabCgNwOBeSQ zvev-VKQkG!@h?|N$0{`mkX{mXM80mFj%UjkQT?_QR~?se?c=sz!s`Y$hH z&hO&Zi2o9qB1idh?>>rDk^IZDO~3#S(Bmv9rTRbD{agXQ?0>xg{`(2l?hBWcvm&D@ z`QJbNpONXyq37ry*TR$9OKH_UTWMszJ)9OtD}%+PSI@p= z*NOSb@h@B3gT(pvNIuKQ-(VmWxInMr>nGs^J-k~F5unw<{et}V)uL+J{?qyRN=Z?5 zqoC>jwql$|0GJu9kFuHd656A!p6-5{;=NJiJU3Mj!+>v?W~q+6mYzMLo2-<(M3&gqX`z<(omoPPO&snKi~P2lSRLd(D> zzGb3xpDFhnQM=gLn}_oe(VC5OHuKKB(r=ejT57c)j-QdiEj5aZfUvz(x5?MQg%?>k zeYaBnWBt!~1{Atrku-i|q(>k@LA`8HFw{@HK1nHwBRJ}ej8Y?)Y>8;=wQjxZ$Ho(! zmrsI1-6rX{xhMiu@kCk^1q=aRTX^ z_ujLVB>!(=Hcf`%3ELF3z_ZMHO;_(p>&8{btC?^0lQ5F+HzZ(hQ zFFt8Go=oxK8phFV>EbK&Jc9|31hG>(DnG@xb@#h@;#>X7Wa-Ehx(*c-xkwD(@R!Yg zTjjnS1&!4tW|j-srtEfKNSWYA_Y);(B&u!&DjH2N7Y8CDv!?e4K+v2C=W3XTcKkD} z`RkRG_RCjG&ZK&)&1RYX@}<;y3sKPgYJotWcCehzCt&;3d30^iH3BZ$pEm)SkcBI9 z?(K~R0KLKeEq|Xv;eMdvcC|~UUI2L_db~$I)-1XGMqa9OUYIkIc&ftm?4`4On(+#7 zzq;P8Tbp6S8DY70-;@may`gc$=83lQAQp{uJDWws*!owIefF#w)}f`PQrlzo)zj-yTS+-X8OOZVCq8keRK4 zY@*f&3qF0%p{cmtN|~M9)DhR+N~nHA^7gPJX}8oygK2uU`%z;!#mEDZ@s{i45VQPN zL`}N&v-8oifUudy5vaXazlj*Hwr`Dojcgtj@dK}dNakji-i;n#-B!0o{tMpT=Qoa$vn zoo%{?w$ZwqAGgBmWi0BIqZjq@yWLD&rqmxH(?7q-_(S8U{B!Rv(-D&p<)E&biM1ja z%?61#P*SvmFM51tCH1fEUuicQ(v1$MmXzOC`JTvFRmm5n7gkYk7}a`YxC>XN1P^lL1y4S@77j>pd9Dbn`_vCZdOUa?1?@judSXB zFx#7o8i=hJgGrw{I*XwJcR$gcV)Id#?HLQ7u#@t5|xZT4K-Em}RB z%!p?ps9gYKsf0e4fiewpUi1<)9*L*l5k#)e#auLKPN`e;;1d2R%pARs@vszGn3i)G zx(~9LaKEC+^b;bCq7YPCaPkme$q;ytX(8i!n~mvyb+lbS0@#Fm<-L6nG2U<{cSNC! zFucHK7wR~N-@-{$&q{A+5b-R!4g8q5pm}jVeV8$JinjvZyFbeHXmCK}k@0nV2883; zrHf8CKRaAp(jPwogLrKqxGaUzQxVYX{>}g1>a{_bWa-d$;b+*8;_4;jvcq6r|8X1g zSnaW?dsIH5{t(&0*~ap*L3(gVvnrEw>T)JL^ZU(|d$4obk~8~v`!asyCker$fwZPg zQXdiMLv(A8z;JH;yid(2wBx3u8P*{blspl2 zxH;i)I`Tvoe*BAfhShZFyfQG`O20PT&3>84yN{PX@Ok(&xfjce@}$Khj^{6X5PKa0 z?dr)K$gq#^jBxlk7U;lFC=0K7Ha)FXT{GE?qAb`_9s+`_MbhMB^h53nuQ9d^Dy zNYcHph;*V~`6o1o9XPUiC{i>GP>BnGHp)7s&9yIY|h6z@H zjKlBVntlae7Htamz@GXCMP)0y;*!ZiF7_r1))9?3LY+jRej}nuxQ{{G3<-K|7~1vM zd*0$91-odVer03%7J3uXKj?X++R*2_1>5gAkk-X?yuzsrn@nt(h$)$t6~W{Bv_?m> z_dsGm8i?>e8-(Nzsm7c6@+d7FLmz6&#r$GY{Qv9;nd>B^gxbx&cW3nzk?N@UYZaa$ zx(18K*;u8?C=TH+>{-@=mvM+qDHJoc*-W@SVtPRSii>W8iGIWv$V19x@h*$gjP1Mx zd{9K3P@P?dq}bXkvahY0^_iqnTw8;`h^x2n0@sivQ24_m24vb3QGb}9R%vjg+s}ZF<`s+*;lj((_r*V_{h!8~l8XG649!SK&+!J*P z=xSKA`@W494;5?262M{Rw>TOvb1jJoPBE>pJmg}hO{qIN`5r+rA6@p?_WZ-GeMTD6 zvSw6hlwxvburEn;&ob|Xxfh&!L;8LPAOLs@AA0JPW98_KEk1G>zBTx*y0`jdzR*l9 z{C%yXr?0_5ROKt=H^GxLgP=>#R=ed=CLv^c#7!3I_X_d3x5*oFU zK-Pcmaof;q1A6(u?S_wX`(z)Vxy`0Ex74Rp{rg}M%6z#${iRZ#CFtYF9+WwbPP<7? zuG^)P;KS@Jj|iU@VkOJtF5`u;?#&ms0RlRs2mdvhj7(dJ*kMMtwi_XFmk{S6dK701 zPjDal_%-M6TRhaxv~VCN#GTwKDw-v_f3qJaAdaw3U+n5aD%`11z`1}LTYMX>DyM0` zEF_47Q6Z5#@akZWd2N7j=!d@7q7Sa^3ZolGNSg1uZ7Veiidz221s)6n9{#E;`@wqy z7CJciR7mDGHf8)=`S?sgv4KnEiW7jn!0Wju7rOBZe>LfIIViWrd}6%UVY{;C62)() zHaoCT>zegzq$nbK+fjEUCD-?K;Wja$Z#(P+-rM@-$o;Gz^WqM!#EsU%+1kEu|1VXZ z3_2TNe@jF8m%LZ+ogq%UWc6!I*WmrPEvh+*C~`Q@7Fm9ANzSM@s zXIK74i>VUg4}Ouh65#r5*Qk}QvB`D9x>vSzkAkkx{`bF<|1_AU*}06jG33kzQ%1dx zqLu^^6nt{ygr2o9FPw;6F*@g>k6fuiZZo?I4kr~h4jI1$1jf45LG-aJ;)#E*u!vkE z2^6}^s8OV@%ErewS#4EV$Ee>}vp$O2G&8%jxA-gLFRBS12}Zv6O>Ev!DlG<=)3qRn z!!JSkSQIoGbFRcA4a?~PR<(8ywu$}sXk$}a`YgO9stwvtQmWE=+7U#8u@ws;`rTp2 z3532-n`MF^{bJ4(VC+n6&Q5po!yfV3{}zET6(ZfszEMz*Sp4(?=dWb0eJ517gf~|^ zFPi}ZoxQ%J@K|UT%d!bw*9aAbyDdVI5%2nYXTsx4AS|&g9ab2Wv+}8x)R;~^fJiGq zp6T|AG|u0-SIO(1Trp9o(Oa%lzzo`(6tY|>zQ+2Ny}yw8osLJMXLECQb5K6cD_gLVB$}M zS4A)(#G+LDuwbG4e*>bufS|JF`i_!R4Ee{O6+e7czmzbg@bBcQc& z77pmEHeF-UNoCNC$o5axxM0nbxf%|4D_qGXzcUrdz;e(FpwOSM6RY8GwwlhX=BIt{ z{-ISrf(OoqAZxPZ{G4#SdvhO7u+3WVnhpg-QeA-&uyh9_g`#Y#}QBNUXC9eN!JM z1@<{RNnq1O$kW5%&_jp)G5{m$!lQ>#d|+IKK3 za&P)eX$wY)_yf-+F}r#IG*J`{H27w7mQoU?C@bM-6ou$+=ktx~Mo*;Yjdvw}#&#Rv z*s#)ki@y0>IFaANWVKi`mq2Z#c`JGkoGAZsl=~VWwgCiO$2WuMy$(XSZuTRagDm#S ze_fWHw+4w(WjxA+5SvY}4%=e19;FpqPBwa#U2e_p1TIP3K24YopN%^mO?RSi2eyF> zR;Ol~?es1VCY0B~Z1Dx|_J9ZDRk}`~s-$5K`COws;E-(+}a_ZdNP z^Mion?ooGTV+r;yfuRUvM|d?l;0HwurL;5LJ)^t<6tnA=GYzH@&sO~#JTH)hhcUCp z_0grDhB1BgG&x%{SBPXQLDAIMm$UG%IKv7*0XZ3ITyRa(_0f6wlf^cLVQzt2D-e9* zx|STTk=eqoSJC+EudfTerbayb-yx+sZf!3?$75!DF46R3&~ouJ4(j&%Qp5TbkR3|S zktb5WgTofg}K*Nb|PGsjK9gb9Adms_U7fk|SA=Ck$2dTl-UN{BTau^{x} z1$XGKx@(z4x3~G2T)RuR_SWiD{&@~0=n1^7Z`e++c&+*J5gC=>zA`Eq`dFiWwwdO3 z9P0?Ac@y;zSSGow*|aP*?(!!Quq(~(*C}(LlSvxn!Gc_5Mz6%ym)uYdo4kG);&VB^ zqR^-d1q~|%)%*;EGazEs=FuCUE|?iackV5@_kw4egnz~+6FA64rf@mN9p0jO6=j>9 zXS_AY#&Wk6Uhd@jDb^sF%4jK!#s^z-!rpLY7kCYxW^L?=+9o89dU;BtN2 zol_pKYHR_egFQ*)k}7L2PhyQ!MV(uXdF)X;iQZE-a@(I_gu>g{`+`MtN3+l{#A)6ntwbW2~6@=W*gR9-ne#l^3u-6m2Nv06F) zSYcLaJGo;|K`UrKjxQG!7{^)1T3zPatkqftq6A!tG&;RwN4BuOQ(!d7m!z$3ZlKWu zdvwJLJRhlHHxs3-2o4yKhST|?cP2aT^(MC}xA_{Rc|DxU^bHf>m#o-*;>a?_e6mZt z9$cf90oEj+_40amQYI9eq)Dy^g`qmETcP6FYGAJx3!T7utq2#8%R*`3E>ZP%%#x1S zjz{Hn6NtZVSn^pgp00R$fADh@CuHan%VFhrO;{M}03~E*>K;ma?OsZsV(QJ(dUYj+ zsOp{Do1MG1RrNXVwhQIm1dk1e+Ht>;2+$IBJF~7=mcu7-j-&Y9aC<` z+d}{Cf)%e-!47!Ow^Dt9gO9F)YBTL-Q#_K%zQ8&ckmNXM2{rcHWcb2k=%-g8Lvi2F z9fIzD=oMqn{oECr5|C4o<@OECSUeGwS}5JG^doKTDdl9gM4AM3vyCWul)V_|rJhm` zX3f$|*o^=x<8^IvVQD9niB`3@7tRkd6LdC%0Xvt`_w4hXyeBj;zBrOArtGpGQ0Mah zaHVqAmb&o4%iT*PRc=Ob%nzF=_{!y4hjc#Mp(wBej@tMV264z)_#GNPoNf4z=^k`;IYdKjxqsM1Ux z6PU%|W8)kLdv??`ejg=4Zp{pD^KzJZ*L{dI=v_#5HQ-$ zsw$pY;Y{4@42tPQ02kfQz?81514g+;1gw*5y-#>yQ|KJxd>!gMN#Cd$$pGYm!?)$I z%Yi9j+ZC`OgrhB%Z;q3A4+X|^7$;Cnkc$)8t~x%sjfOl@`4A4Kbu;DeZVCYMBY?E1 zNIvraPUxNd+lCA;!`TM;piv zu$lKGpORWgJ-YjxQs7NP*5!xxxjk4fW!D!9@m7U_vv3aRRy3fa@6X#uuO2 zC>e~Oph?Ku7zIfF&mCu=gaEr#8>nv)L*)hjBpaTwT><)u$ zEB`1$fRSTDj$IP?JhMvR>!M7yZs{)MH;ierT^Ex3CAdqTCArNksYWm{lAG+fU7SKz z5!){fCCj28)54nytA2e?E3sTmk)L$}zSO-!4Z8+I5pSV99CT;7+>z^N1aWKb1-i7% z?OAt>yumIk^Nyc-gJd>6+uh;)CfWc#L#`g-gpywhU_JNa{2x&RInl>1+P&aUohAz2 zg^?1vU{2tY8KDVuZsE8f%|btYp=wt^^(=Ggy(*I)&tHoVZ49um1X{%1IS7wIPeyrZ ziNwEV)oWLZ^(5zs5_Vzx1O3}$jYL0-GUYOi47@AU`>C6)Yf!p=|JfquhvHX@3iGIB z+!x;J9Fw4E_|L}-6-q>u&U?^-i&QtcxkRksuz#)^7tw4NGQ~X_C3gYdpw-=VguzIV zh5y}`ow345{-56l{3Tm~%ueZpUzxhO*GpD^b?yDkQ5EDQS`uQ1yMaZ<9Zf`F54So3 zD-u#;_}QH@Ri=3WyaMvj(qTW^{s_NCYAoMMZ{lb0+UYdoWx%r?ECzrXW#=NP5-`{g z*VT%1Z3l|Fp11{>t3U-zznqq!O3g1;FJHUIoB2LG;RE<9K7RAP0phzz*j6OMk>^=! zl1MV)_{PhS-^Y5*t9VxzX}n6};?KVR=Buk&-$%l7(Qj!_McGEkGdz`!=P z&5jMBkzo1rN)-$v{lZWfpB@Pujo%fv?4%qBDU76HX@POfQ&da}0#m2^9wTca!1Yyb zjHkoNZ`Y^Ve}2>iy3<_-JVcT(I?VYfuXPbQv=2;1uIgu( zJ51tvcv;n1VtwQ&ns(OVN`SqB(?w?jnpvJT7Rho2NfwNh-Aj!vtJ|)$%6xa`# zWr3P+Mceah~gC zjD41DKUn$s$@VsIv;U#I(epVDoVGH0)`prBo{ah0LILxrOsvvhS^Z)H=NUgJtM|T&W2lbe4~_VcM3BtiQuqy5N>;yn#P4)29|Wgh!@J89u%e zwXXXx;glBX&N>;<9qW_5r{U_cDOU#0Iig@#K&N&MXc8dpjy-?E+@G&V`yj6v=LVdq zjAp+_KUFz#@LBrEAKA&pE-VI=Bt4xaRR-p}5328b!* z`6W?Q#QOjuzS0G!m}H?(pjpx*qgYmB1bL(Ll7DjHuWjJg4m{< zy+qXAUoa-pU{Ijj>q!QEzaegQ1s!=YKl|t!u5=3i$!W7ZO?%Ng>d##< zzkZhS9uqg1DaQnf&A@LJ15#dKcWgS1=P4&D5j{%8*x$siy?G>I^$>h>;;ag>HW=iK z?P$~CJA!MV@h4BVo`pslmMKzZQBuT9{?U!RylkF(yhzxFeZn8=CF7={=A?+N-Xbu% z0yoZQyPz|VSGX&l+339yPfnMy@rE_=nd%vmvxT+sM)5jabKwLKJ-7F?ecn$%T`^11 z1O5kheJ>D0o!tz*LXf9?`<7@q8Ot;D;S<&?P+<{I57{7xo~kzzAX%2UFwZd#vS3yy z9M$9zUNxfG6iFl(8B~iQeD0+G8}0RZ2+lQ%n9miTclXcshHLoWnc71cKd_^8^ZHIv z$v!_uUJzv;zsys+*?OEAC1!yGRi$QZjnP3D`fJ9ld8m>wy=O&(m?9YshcJ|n_e39N z8cKAWqWV8;YZo9X#0mmY?SD#?V*NIWkVtTt{IQJogYZ)+XWElag%vYLn(Xoz*h%cl= z2Ox*p^2h5acRD)LC^i^Cmobpj0kd0P^@^ZigH4@3>;Cr0oe3H@9*|#H^|1dlx@J(n zZ%WN7-tN5O&9+%E`pfjVwYA}#5GZfVk2iz)fl>6}pIX!JG;lx@V)X!r(n%x~YT0jl z5P*+?+<~VG_JND*+af0`7t-75m^LPK0m<*Ndt4y2)!20eHZ~}z6d>vVdD!|?NCM^P zKS4|#O#=qE6;tZ#OA4qmOEJN!fTeU!bk2}$IeLR^DzWrSC!?U6pB)JY%V*VDjJyCA zod92~!pDxC3(^{ggGKr=CsH1q84+)3>9KX7(}y?GD+6Zt7(^&Htc1~8*XJoW>?FY7 z5iGEtX@*!vyZOmEKb}*Or;FdKv*$%%KNv7jD;<{N>4IU9Eh<=gQ#1Ws;);Jy`uYJ8 z7o&!WZ0j`E;mnC+rg80XtPst(3ZMZ-9(bx>!##ftL!<$Oom@1%Iu;6tq5*sZ74;qW zIHzQ-MsGPFI+ayj*qC3ZHCRFI3YHh(^V8Yfux{yH)x)|i7-aynlL3!My2MPeUc><2 zBNy>I*`9af$g~lNlf<`89dETNcB1mZ*3kQ0{?2QpWm~JN!cLj4_cQ<^DF&N99C)J< zX89EHg%#^HgV?)yKAe*J0B5A*lKWD`&ge!Xvc{B%y%Ct*rPfJI_(4?G_G9d=FfrJU zz4Iq&zjrK-8Fl;5gursTSnUeMFCVubkBK9`Dg>r zP-W4Rqb2l2I)!BRplF;%eZP$}6(6aCzcKw9C3_~cGYtkFzSAX7&V zVtd$^4h32MK(aT%so%#kj;mu6Q8<1ltV?+Mnq62n{m>+}UHMrr(d!GfvvkgCDx+4r ztOpPEosX)#Pc=uQY0=EWQv3$^GJAp9V2d@Es6bcl)y~-Oh+CXkjSY5;tqSRfLaGYGcE`gUt5tK1fAh$2YI0Gz0OSu56FGMxT}Z{qWbH*r4UYCFI<_$qu~`HK z3RRzsE%S&LFnGNMT3!b9etH#1KCAxM!kv<1UR77*{0xb!iIQX-Mfh5zi?(SZ{wu)~ z8?#H2xJeW{Lcz9M@aD&FCQ%*ew=i%1v@at6&#eORAe`(85RcEP(2PHlyOeRZxR%Y- z$&0p33W$&*AO5tB6Gf4p))6t|**39Qt+N51Cn|Duo=uAL^Ydn0cb2*?DKKd7Mgf-X`HA7(m9Gg0*)C<(XS&U7Q|(`rbpx znS#fP%$lvy?#SxH$PY#a!z>z_5C+v7g1w3Alz;{$q$y_~sS`>O4d1+xR7KxmjC)KX zDgPi0yddwsj)p3;anlpn7ijE87ov!Y8U$JGP90HeX{>eOY+f~`QlCqv^lG~~W7e(w zN>KXvO*o^{gKKjjB?ZV3j(dB-n=>G6irZZvlTW>Gl}&Cys$8aJrGOae%~T?#R<1oZj>| zoCO8`P`FRjfkG8Nj*O}v9oAg^U}Tf-6$S}g5c3`(>6ySHXGgoAb9`uYIo|zAwdkW% zv|Zb3#8Ir#8?=peG_(pZAjEmi_N3+N87+dSrkm8eSUZRxM6+y6h^+gf>`xE2g=e3w z=<8`%y|mE$@%Hn+vlP}w>&J#WH4E)GVK2&7Ejq#_yWcxeiWhIJa^|>N;(kRmUxQ=9 z@eDKQrfqP^3K-lJo zpL=e6Og)ZPE={OfcHU5X+6Qa~acw+}T%n~NKZ#sm$e|*f6sq}W?3Wm z!{+kK$l28%bu2$Nj<~3Fug-{Dkn3Bo0A+2z5~h|roEnO>r6)KP36osWbR>1o=TcZXSZ_)fzBnXIQWh_9gZ^7GPn=a+TJ^Nk<~uVYflTD~HzBXclCj9&EjyTP z-(81%NwxIyZPP|qN)`y8uB1Yhpv9?hO-ED%hLeZedR%3^t2)!FIPG+l$GuM?HlOmV z*+Md5o?KQ#%B|0XWC@uI{nc-LZbS|4M+}<><Z)~!7A!ZCgT$KW@f-K*vABo~)&^|9;H5NoArlgo)5IWO7= z9~gA~6k+Vn5b#U}!PEtPE9wv-m15c#ppMAFw0m-i$?eX(*U>#*@0S6qrn!wZyzL1{#AD($l;~NA zasud3v~;EtY-E4-+pZDY5SRE3_>HPBN14`-bpK@KSST^>t-}x*Fd)pUt8fb0$9-lq z(T2)?winFQG9^S=$$RhCHY+D{JKGW!_pKT3np8(NeKdf>H;s4l-r|YE@U1x4cJ#_~ z$j{iGo3`7$l$(|&)-Slwus?5<1|(i9WXg7f;9wFsCJ!pr3^|I@4Xind)h~-Fo>+Uk{>Z)&4n>Li2Ocaaf*9qepGy6P z(ErEUTZPrNgj<`q1_|!&4#9%E27(6n5Zr>>!acaV2MF%&7Tn$4-MuIK{O5oAV(+VN zt_xUIvu3TTuii1nd^KKRV_;ZA;TifaIm-zSwa;0Kd4e!K%pz+xkm~3bgV2Z3mO4&i z3oV#^8O+F3)`$bK0N5QpreC8bVIPvOseqh2fPIhtAU$WtK~xWYOy;2ur6k&QB-vfKCPXiI=UG`G{+I`}e;F{wA< zaNV(^fB-dV9)nm3hcqsDT86hWMi%&Ts}cRztCM#z0|59>1b0kCkAHy|2X1f_%+T48 zhXrfozm;i7`lQ&wYeeh->>12EvHC%UaSTelgP)95y{}Y@J-^CW1~#mU<$nlAA9Ymy zvE%7VE#i;>cyRWf3Urh%{$Vif8Bj=t-~bUghpXAptE|4c;deL+N2o>TgB`+Ngg0)l z*NcJzHA4ulCMVPjYP|$}<5ID|OYcZbi;-`p=MR$=i%scORT-;JU?H^-XQ#d_% z_q&q<WYG zJM}x8A^FpwHs&aIpLV_L60%cCQUu|J06|j+)GtguIPJHBDwC@kQZyF#p+QtBm3KV3 z@LY5E-??0&OA(;1Gf>=KQuiMXa^8C?7BI)g_3y}h3?P-DkQaG;<1)fArvUi;(|El;zw4?iGXB%&-|(HQb|L%lf2n6ISRY{(l{k1r2%k##e;YiX zAzz^9oA6KnhCT1x4>7loKR;ZV4J9zf(JE8Xsg-G~k7z+cV2k|&J$fF@-sp>1tjTcp`+Mp8po<){ISEC`d%+Q&&K;mT`oOm{_^_N$ zJ1uh|N>UW5+CI1#PICTIG{t@t3w=FLjxr@Hec!54;{Z+g*~xd6@q%i_#b`e~XYK7C z*l!Yx0$?3}>znmt8W(f#xh$Q%ePP|{LVf19(iI_QzEnS=v1|3hyb!#4yDLu37E8)_ z+8eBVuX7(U#v!&yLLbH@fm}cqIMECUCW9sgaooEwZ~#En#mPLDN{#|ZGHTLMk-zYK z%|SrA%2qNSny9nlEfi_IE7XV$TvZ0_&Iw;$#suRY+umFa0HhO$m-72x>iK%;_)l?J z9#HO2W#hkvi>GW@IRO>RU}eRcWYi-1oo?tP9K?} z@HlNG^}Ot3GTe7*0mS69u4}**%Olnc2q5Vvtm;?MM#)1G`kRU5 z+T2bG-nn0uQW;9YaNopBth`w2_WV{}LBxj^ap2V!+J;jporwZ`V6dC6B9_FL;68h2 zLqS3|#S7vQYH?*R*)+?YGS6j7C6x~;_UBdMi1Sl@$&g@fJ11!U8^)iXPycPI&@T4- z$I#wF#Z6Mw0rgstbPFh$VlR${rh`BLV8%4=0h1~*3Lty7M%vgK8QNUwBL?7*9-dID zE}AccaWzF#crUD@fli?+>`7x8Yec|~khP$AS<1x}A_49Xg^I=>cM5(u-gICbF#O&< z!T;?Z^PwG3wZgExjUq+Gf}o?hukb=ywThS}IDhb{F*yU_4VxDi$iI>NX&_c97v zt#9A58)s$F=b&+NUtp0Z6H1p%_sUkT=W`>+0WebavNC-RzZ^TBlR>A>H^b{xV=(UGav{q#z6Md$ z``w2`K_A%jQ1dE{)8POdA{e`c*zk|-NiFLdZ{EvuSb9zR zl&<~F3>m4{?E&>cAIYe?*V~Kp=oS59)0VyKUB=&-k`DpPg7dm%hJ6%rI3>^y$KiazLRxAx`6)EQTskHQFxgb@ee$HtX3EqANU z2RqoAcP#wB?uGA}C zH#9>|`SK#|w0yX5_j&2}j zB4Vs9ZcTFG8~*&-UAucLyPb|HQQ?@6Uy!jR-Twi?9eOdcbC6T zARKvm#%%VS2sds47QJ>J%*2D;Z;c$M{~vDo!5)3ua-vs`)ZPsxDlbc7Away49a4yzZ9r z?jJAMv(;U;q$&3it<4&l3= zY~!o3#_NK3Q3BmeIGAhf_sUwYUk;|?lIP&QUg8A(PLwS>0B3J!DaaXd5oB@FsWm7> z|GMQ&Oa&Woxpz@D(bRGy@i7_wJ(s5a(mg)@VkCnxjF@Rv)Iit&%KC`!>aBaauyIr~Pfd?Lyl;f`u11S z)24gF|MKiWH0-rRv|1kFJ=R8Q9>%GA)`8#4;ZsB{#4eC|$BN5+*Ea*R{eqH8zvT{F z!h#KalN0U?UB$HM-D6>GIzu0&%>O0q2Ub>wQjL1WT|bNR7eTkfkP=_k=hnu&Gu4W- zs^8s<5cVJ2qFqqNBhRHjny!YhTMO=A-9vNUXKbW~T=<<`1Hz!IEmiiHwItET)+F-w zEgPV~I`whZ{2rO^ACNrxTiI)zl8zTY=HDTKgnRoJWDBB0XULYZf+Ma8;N%TIuW#MO zL#F!Yh$9v1i6h+CMFf{vf>^wN&z0pee=shWE38$1g~$0^bFxg-B!$}yVF&aX8wsCn z9Px}x9~B9Y?HA1LksLJQHhQ-3OkqkK*Vs^vM=u@oO2b6A>&MGqa8QpZ1Ybm9QL^|N z^>V=d0?*$}pLm#A_1=rhKqgN!lmYm|?o$5t*4giYG+J^`b`ZPHn4d2EZzQ>tx;!Py zwck9o=B5?TPN$20eZNxIu>(`t@@17$zm2q>0|gSX&l#T4)GNRIE#L%&YR$zi-cYvP zdJ0*mTTO@?o!(SRwW9;Wam1}OIdj?05`N|$FQPVB!U6dP`|=+=uznG<{w*da*yXU9 zlEy;TCDH5P%Qo4Y?J_mx#>xgVHYWkULe6VKO^ypKOYe}fwVH4S%~pR8ACx7v7Vo}( zI)a&gsX-NDBv(C9bV9l25f(l1$SXhZgXf3J`~C6SdOeWb}f=~#+<0@^I(v2DHR#={FUX|L-UO)HTd`LPF`V;Ps8|?uV{~V40 zca)ypkC;`aZ_`6~bc=tn9XouPfwBw4D|Or^?>F>Zy&5D<$(LT=X6e?H46~2G&LQv@ z#*ZI}UUQvbG#jlY=eo3qT&4{$1I)YLKx{&95lpIrtEg3*ba6yiMI)v#KTn;R1WI1x z8se-Itb0)B_Sz6WqK^^0QMttvR)(k$CI(pXCzDb5s}sx)Z2dt^&Z0fWw2#;Wd^m^c z(8^Qp9SW|_D{OX1*#`MP&)hocXlMZE{t>;JX~cf$ii62A%8eBmgEoI}4u$bzN7qu@ zPMijk$g&eH-I}k3wyP)eyCM4a;kTvie;?4fe}BYWYt*PlssBQFG$t4;3YF5als|cF zi-yz8ZZyi5!s=dzPcc^^4l7DL*8&4mWgiJ*U>W)%cQ|)_+4+P}?c;#*J74}8MANza zK~r`d&OcVZ^pnc)#*s*oK|0Nk*QzS=^1SFQ{KV`#+q0tGhPX)Q?i$ zfn6Uxz(||61_5P;SzJE_o*Xvh99*De(dm$OG2h3`TwImx*PA~DumeILxo3H#;Sm_y zGD_HL)UN8T1Dzn0Q<~#>dymyyT{>OPeBRhaviJ@Qwg`=i;Z1^5s9j00(ywGI)uU7y z2+j@*u-Z-$B>5h#>hL@--6+=whsKu-0_SQvj+nCWV@em!tC&Apg;y3;YD^72;(Q=t zi`%Wft`>T2VK01x4s10}y=8Y?{P3C4@M+gE2K)6F(Wi_ihcjt2myL-QGxEXv`P`aR z%EI&}r^J?bK3xA&7|3Y7X}wz&mBX7YkR%!)X$}RV->8Lg6dTPQ#gz9VPF$$>%vR%h zIw4}SYof7DNYF9hKHO4=kf6#auoyoQqo|q?IL1lZ8au62^?SMwne!q6ECt9==TClM$pH|mLm=`aztBh zceem%UlwLil|Jj4kXHnS9RfnsZ^xk1nzwaQ4b#HdSt3u^0VeRx74ak4yNM+K;s6v%@{jjtd+9OgSbaYND9%D}~tVyqU#Zexhk- z7SZ{0_(iKfZotWu~z^I?BlU8Jx!CGRX9+o)vn8gwHx zBZw<(pmx~+6Bz8*hk)a+Xe1aTUe6myo(vmpQt13G9oZ0RqQM$zg3kAc@EN%1_tWFq z%J_m2z}j;=#2HMJyI;dL><;A&4hqjjPuLD9WW#jDd$|6bAohBe1_<7~v9^1e)sQv@ z2Y;h#DcUk;-k3(J7}j(JdwUAwCL_WEVWoxA z3f$lY9EJe6f|K}_E;Xc97H{)$)d&vCsrm<+KNa0DyqW?D^kpVMC3b7ht$Hn@$5Cnn5_8p6gmN7i=@Q7_fAZ~ z{<%kbH5ixHo)2mb)!Wb8Y-yC=I6VNwq?6MyOs}QBgm46g+GcXkDUy0|1W0XfTflv5 zfS8KSdHM#XdKn%}EaCl7j!DdC6ny-9CjBykPc@mDV5&r+W5i|8#`(aZ{_$L}@&BUe zYkNo27W+d{ti@-4CvuenAYqXQJ%NCN9p{xtB(%}r5I^rm`6 z>=J&GixR6W;mcGYq7eQLaXWQ^cr4!b$K^}T>+{uDJs&l_*aqMkPlWNhoJW-dincbO z$1Vm9E=(rY(#`I7MD6FTPq(t%oAE9|GF{pq*pb_7k0iD}8SPqf&A%h=nRP~8J<=dM zCnGp*`TrY8KwP}==wSP$;(xsWl5nHmN+6Do05Md#W&R;rzmjEnXv-3b!Et*BVs~$* z*UQdS%V-)uy_Cr*thmo@F}u@iT_FZ6*vT65N+w;!5^)fWMKz}bxY>-Q?5ei z`{Nb=WzK#Kz(qEr|DUXc8pIQ2&3e0PfAJZs&F*-ZQA9++8TzzYAu(jEAt0zykAj6%4=iri5`W@luQGNcR+~rZW zChsh8Jl$G;-CyF}i1<=`Wx{=>`NY&pL7dL(C@^^jo5~@j3VONWk`5A3y)6C|87XAA zk;2z)z6(-Zv;p~epdYxS-t(P)^>_)7gD1FnagyF+)-S;LgT!>};-x+5`r*ufiP;*j z)v2F#*ECT*VC_h+zU@&Lx{UIip-aI!2oM95Y-_el+G8_ZZ2I1a-U;|oMAm|P=3eDL zWzhfL=UQFAzU+mzsJZv%K>W~R`^$YA{U)sLB6e-7)&1+FY=5Du%6;+{)6)^p6ML^JH)MPMq z!-Nr1K$FtcL&tz3GrCJe2RA;wh=#k(bY6Q-GGyqBMjk$Wt9Hh;)m8cG(Ie8+_o|iW z?M>#JmbH9k_bj zrIfHkE0U`i4{Fxyn1n5TisAU)!+ikT%t>Lc^K?dsg@(x!ZF@am&?On51XlwXp|TR) z?xP2n{-J0!ek!9jry{5sv!q3hiXg6}L+F6C%GGgZutO$=c0ERpDJ10DNVRE?{kdqv zg|Zi}+%=~W7yj7??F)-RaJ+?wl4e_qS`mLOo~q-^E*-(c{K6d8 zfdZK9b7bXQkyE;evKD#Xjtv}C?@ANt=EXZ4&qu1qZU;ZXd)!;N3-Q@uilTHN?sg`5{_w!z+P*373P46M9M1M7uxI1?PB_Vqx%6EF6olu-*z zsRbF)dyxf{*FPBkF&OO+h}2lhH2u6g*4cR5yepi0Xmo#74anj6u9dBBiLX(WLTfL1V;VG^@xI}Hx1O+T zPp^)OnTnR+WDN7+@{3nqEDEo$M%?0^Ir;Sd*t=l6DRhO;d`gFR8v1brVgB2*wfcdj z&|QEbB^A6(lA(Zl4!i1~bBvqg)qulkn+~dwp#2-wA-FOa!Jp$%JF-}A)==fc>EaLE z>(Ej>YHG* zR*5*`ZcHkN!y7}?@Fp;JlcnFeWH$P%Nb^gCZ9I+b-ijrY=jX;UTusy2w8rUtt*`d{ z3PQ(8RHzDbkWe2~ym+BB4doi4YJG4UWz7foe?N>F3_fogMar-ZnHEs=On$T(*UIFiid-GX3!KGr-V1Du3wT1-!g{DA(H3xh_%HDyH@FX- z+9**(bWH*kldZFgOgNqXv*C&x%(;BeplVIzId2e$Yh_tdfRVMqs+l%4V-Wcl9gAKL z%vg!Jnr}lDB%;sa+&LjkgI;4}mtD&V9dc<|yGJAV?H#-K&^5sXFD?b! z+Hys9oyC}lsBEL=eaE^`+8cGC(|D~lWVA&EM26xUNTPJhrAe5BWK|zh|A>Kx^K+vXh2>-S1#^U7SHRdV$Q0(eK zLr|k#Xw=}YH5a1b7=2pCQ8{cz7`a_GQdxs*Ube;aY>!5@XN%%p){vrLJ@U2XE*+k z>nK8a({zoCiJ~KPNZ-WpMQQg(Hp_{GnU44vUE8vk_mxeHHWq`0;lJ*HVO#p zqk;QPBb3g2+9bJ2;c?lC#WUu7^?`sdt}miqKQOeEa0&+E4~+t`#5F=E2vCbq-JSjw z_T&?^-oC)Lzi=15HWDjEk$Ny6ud4Qk zDHZ{vh7uIfr}ezgZO>Bhl+Y~+g?MEXPUk*H*A1pq<1PY1z$ou?$SPE6lqf?4qY@J4 zK0|gQL+ElFKsc(<`eU27s5i4mKnjrY*t0WF1Im;5Bp5iu0PoOw&yB9(WVlYIkGO(G zp}uh`#SLW&p}y+<(BS>&T}UkzOVFoWJz4tn$RC9!V{^Ras(T}`1Uj-IjD<-f@1aTB z6{tdTK%fdBj8Gc?`ipY>Z4cq9ONadk$t5b+`r-bl(XcF8zJcrktpH? zXFmNE&OrM_i3ttq=9qw^xF`@|(^?%puM~*tmoMC!V*O2JZ{zet`E!A?xs`m#6P(b) z9t8%fss*J7$rOnlQ`Xdvk^FdqC6W|Jq#Iq+$`1Z>MS#y=qJK*#$y{SBh40D zaad32ZX(`i7NwL+ruS!K@OJlq*-oFWQzC#3@fShC0CI#{z>e$I>8xrPdn_O#%A!uy zFu;NU=l(bjaH~Kvn#l7O0m@ZAo%Ut0MkQyo{If$Ri &atOB z2g!BoyCkuKjR&Ql<65#1$$a-+9EDh}K9@9V5w7s46Gaf_v9bu?=cqrdZ8YhV-thRh z5)i-P+)Uaeho=}NhrPXAa=qty@&m64<5}MQFa(855S^ZMXG1 zzd#$tvZ)&@Wt7M-G*a3s=}|2eB4)VIC#9w$VafF?a(@o)X|A1ANRQtjO^ zLr^Yn+;WnqXlpt9Cw~++Mzq1E#@cRlwcI|9=C+i%zBY!o=;u9iBp}lZb+D@DHHqQ%H70kE*lH_p@( zHjd?8?rE9o>xr&liPV&y)S`U8rf^Ax&5+CN$}w4lGO99Xp}w@rzk@3TolmuqA3x$` z(Gpb9gz+f+Gbh0jRU7)E?;fz6TuA*pN;|v#gdqrXdCEl$X-AhqeA=-kqW=-C zH_WR|R3p?uO+CbzP)yK~;2A-BJDdNWxY|qrGj{KVl1EQStdRXz&B>*An+Kw$RehmIop;9pwhr zIac|{=kZ7lb^7Sv2dAFCO&gEDp7kN9V^y*b`L0UKuHC5PjWsGoW~1sX%q(|J2j?MjT+cf6c!p{<=? z5IB)jVDe+04AAF%FNB}|6iO0bf8L{mA}u)J-!G%bGl6qdkbr;o#&;2YDD!vlWR^7( z_h}@e7$Wl9=eDWka=SLQ35!%;==?>+#1v5mnAoWoyX^os%qW9;6&24+iqFD$pDwp` z*9n^)sId|#&(a;s(d(WRW&RuqPhpjsEnLP|l^P^V$|%0L)gJWWqiG|pAF^0?QG_6R zx246CLblevT5YcTU7H>#u{+p$S!Faior!-kX-}gG1pE5)&)+2mL&QG7)KJOi`N8z* zmaxaSEiRqcy~#2iP9j!OIpQA%lcZmVwtK0tB#ut+8PV z>96xD6J)uZEZnZVeyTt)0rlRk1G3CEi>qtmO!Vh~1bi3#;n2jyIA zq{0panF?m)-gD9-H{bsD>PNxa9JcL-YLS{f4DHuQl!d}jGC6BS9I7QTdb|)!oU|DV zp2>d?D~X>A)-s)jyW1Pv{~;epMTQ*!=hny1GrU_PKX{~8$&4l*yz%y13Sp)n?2xQ7 zjc(pALbsz>Ctvs@%GHUzG-Jq1o1~G8T&NZFt!gFv8SVo1ci6Kb)fmZuQN7RIFghx+MH@{KK2b#H#&Rkxc%e@V`4c9aAk(mD%0&fL*sQmiGT2S zgru6oQx=;e_woqIYar^d#J)mb`mwv|Lhio60eggLdooq(*PtR@a35KRZ$>EgV0*_v zAJ)=3@sWP_4}-?{W{IS`oRw(5r_0&wN4ro5^P3V%Z6Bb-kvSCeqE(4+bR9)?r3(@s}SmdRN|ta#_O)tnlq*j zIU#8I5M-iSQwFPvZ6SB6WnV$RguVJLp){2vt~BH(1~{bB_?_ThEQ5^^EL6$VwmzXq zt)2hsuhylV=k9>6CbS_9cZWMt@mae3I|~2>C)h;s^nAj$D=L%D;Lm;bz!|*mH`*80 zHHiz3krhImzdKWwf_zMte5ZSHMe0s6dsow6y_FxNqhtWzf9?( zQlYB zzw!$MK@71~k0t=Te{oxmb5*847_S$19BpSD2%}d=7qjZuiu)Xl*{p)~Ppl zQ`#+RyjbFTc|PtrcX2Lin@#r&VRs7egWbX{($eBlF;G^~Ct7Imvd9j&d|#xBfl(!{ zYu(|UG5+$b6h`I2Z&gT@h)Dk;_w!nr3g>(OTgMN;yHfiqN`grPJ zFGA5`dNhQxD^^!hub`TN-XTScQI`@)ZW}1Ljn#(>DhLkpS(k=IA&%zEam@}KbN2eC zB3uc$LG^1kBpYF_Yg(vzB@odioR>_@!!oAyD0VJgS=fCJ?BWGh06eJ>yUyw;MrYHP z!0^@kPA?4RNY4c|Tz7pgD|Njxlc@x&9=%FqW}9KH{H;uoyd@@v12TCMsV>vYUGeOU zk<4YE?h2g$VDxZ&D-G2~m?v&IqD*!l@&*5S*NKkDIWFKME}x>6G6d zpKSi<)+>^M>p|o7eAr-K%UJiT#ceyC$tc39VCJz&l|IJ9WN%=61imruoNE4AFg&F~ zYCk7%ijFv5Q%reG zCuTlgNu<-OSh1|hD4hAvrJQ2#6 zqxxShU9QRi7yVZl#!`_ENHl&XG&b3Em8PKk1L|*q#_=6l=mn#3IA12{5Y9i8+<*U^ z{N`puh6K^5=RrgryqiyEBBJ_0#mpuCxOVI%b;{^H^63ytthKKvhTVB}1CYCAakXehDD$L=@uAPmHE!kl} zH6fXJl~@}WG5*U*$*}DAbb~hv1kNUI+~=O^$zCe{v}*TUb-#{3>m}8rJXSh=4Tf#n zw!+&_yg;Q>X^+&j`{&0lDVVw_KFqvOh?N6qgj&J-40}eQ6{j27!qfZpUCKSa#ab#_ zd!9xMd!@x+(1_Z+zTF!Z?V2&YN`ke6uiX|;#Lp3_A#=O>acFnoC6pjTN}U9Hk@g{2 z3$3YnD+Q=U*?GFZI?P$z-J>K?kk1KNnre}tA)H}Y&ar|kb&z+h;!k+b?+M@tsEGwI zytC=P%Y6L(_K%xkOrhqU5Wm&Oax_FQT6%8&^d{5=k*^k=dwe~dZ)g!oPt760U`qf= zkgzyDetGvOUeU>80gT&3*sWYhEEih>%%|n=Q>tCNd1kM5-6XWjb^QO~=xM_{p2cN% z=y^+s^py||kdA2Tto<|?X_E5AW$wD~aUo2|AVA{6c@`@4f%?r+Vt*_i0y_>Qg!U|o zf{5}CRq4a3zy>dRhrSKY-RLJ^y$U>HLccyM-{24a`dW9Evyn?3?5OzFsjdl3sDpdb`~QB za5xD>9b&I+uPm@fNT{H0=%F)Rs^rnkX(bHPXK06BV)w3tRa{T=P~T5(E+?DbV9O{} z@)>;s!)H^kkgz?No1EWp_%t64nhN$;U}FA9b07o-wGKMJq%TL)ebkpo13>aYx1sQB zu>J^Il?oyM#e{dW{cKckX6|JqBA^^ccL#H9m-#fChDJ<=@l}=!Y7z~CWhnEL%|}8W zU+<>1Fnj{2v!9Uy44r7?H<+LY`p^^on6&nn=ZWOls812#T>md%G%P) zoW3a9HbvDr{f9@qgSR&=!el3j2KIj_9Hs(*2J+aGvl0KHp+H7u5f|pcp*YI<_Xf62 zK!eT$k;O&Uf7f|TfC_n@nq%q}{68?vPfRIE#)YpMUYF7N;8vy?uXfPE}Q)~3^Qj$DKs4t39$S?y< z{}C9F#soC@|2`R%zz(+hBd1b0EKJWQX@aMa0iz4(-$andZah=H?fTb=W@8zlvD$5dQgg5Y+&pFME!+F&?i{w?D;Z!fc0M(xKy%xQT))4NMQ8ad0=j@tfN z`&;&*YNmXe87=8YmSqu<*dLz+9=}stEngC0w!aY#M)O;woa}8M*wYyGT@}gX7m(dv z+zGyBO>7m6Vfd>c%fj%Mzz27s1DE~a7E}Br*E^=&+sIi?WuKB*fHyBU9M{7MY zj}Kvj1%Z@Wn`_hl#I&9>D!>b=<2j=mw>O&xMClkgDDDn}KNMZ$y0!M@P^5FXI+(L( zS}*;A=7O_d^StBN@t6=V2_B8JF8|!>?6KNKS#v(KqjJ?~vcG|b@_S*(weAOjG2fd< z3i}VK9)Y&I*C2M=c^q0Ub1A*1>zFX|+0W>RCF-pSzsEBAj}Eu4r;Q>rLK0mD%MSb^ z1+qbYk_c}A5)(3c5Xa%8}0|)i~V1)P#U*olf1siXSPS4E>-zPj+6^C6P znL@cD;^V`f9?cMDVp#1*CX6mJ-6)|%T{rlf{pl2@_G7k(bWJbAk1oo^k!F=E>b6=} zeOl~hi#mmDI>509@D$vLk=ujO6m`Yfz^S+{zL5hzk1ze)H>MuS~nH@l}`c|g(wH<%sLO?CDPoS zj=q>=de&*Ld5PGx^}AEnR3xD{#C@DEq<$eReKrs$i_o%pD-JXNsN)vegQDP zmr2IbK`V+t&Ieq!@so#3CB@slaPf8VC$E>6dK%vGQ#HLSw`gAKojv#G!{V|J`$U6` z>NUU0ns3bq6S=rrfoQ|UN((N`wkzbOOiT)r5`JFiv;5K}fjnZ+ee_G8&BoIs_+q6! z%E>}=rc5FORRT8nFTZCYEud_Xe<%2y1X_2bJYwXUNUz^3uqbcj$+|wATg%IwAIyE; zGHw__ffG2Ycx-t1jbC`(-P^m&n+5SEg>3!y{KPzBV(+YtScZOr(ZI;8M*NeGC|GjG!ZDL1#jo{^T!y~R*p<5*pD`1+5z6hhccr( ziqv?UZ2_ppItfq%aHwtIp{>cNy;$Us-?uIQ(6ateDKg$DV(pvPXe#nt=N3S)yv-rqnZ=HNY|66 z6yWCfYIQ8@zV`)Dx8k&+-1KA9M&OazL^1uo*PI^xmC6(G@xGxO;8UY&v6>|ckmB)b zy28$wEjoQfcO@}e0+To%*8|A!!2-rRcfX%o%9ejlh5vk`FW0x1x-!I-oCZfGzHEIM zxYcoh9~(#`K-@0lwYg&ncar0?-LI(c+jwocihx*Mo@`rq-*4nd0*m{E5oXQzpU^Mc zv&1Z>G~uZ%A%9fL#H#f&_HHh=?zpbHUp#nvPin(A0YD z0t;<^8O4g!iWv(P;>_t({9 zh4QV~2ZzPwzu}D}-B6^bHC`5vrYodBrNJl&fLJpGj3JB-cLLGMjCtFiD^sa?lwZU9m23UydIn3D8nq&UX}4%lTN?rSn!f{ZO??tn#VlJKTB) zm}gK$sa2v|VG`7E*Wy&8q~N00d4(D*b@C^@zsxmUp{S8Z-k0PAq`?}1w;;L!jHMR4 zYc%v}i>_lhzT#%*lj%uQeXB#-_e~CmdGCxC`E+gB*svwyUuq-Rx(KGQf+XD6M-$SM zq6VR_cl*l;)=i|s=OP9)!hpa#mgW}va!^n)flfdJxj=+PGH9LPSo2~NG%}+$5wlZV z+d#nj4bT%Nvcmm6f03eHtsHhHY<~I**JhoF8hmAi75HL*5CQQ}xFgH#Ca$We5EHL> zvd20P;aMSpDFee{W=it1-Yer5_o*S-sKFf=5Htg?z zhm?q0aj?`%-mYwX9pl)x)#lSBXLdQC?I7R<<tW-{s*vs26}bYO=E7YdwCe7n#*4gYy{)WpHvv`ft~ z>F)N)?a$SSJY1RIuB#p5I2K0q%)jj1TL`v+h2!xjB$R72>Mcql;~(pkAZ$2V z%;go(#}{~M>~~;4D;o7lD~Lc*tKjiF@gWiM_?B%1v?vGFIarLQJ?|LsIv%a2wmsZx z(eA>0@^Cz0GoSdAo>#8j6kPSAReZF*61ww~D*Bf~cZU-(=QSO5|BwrG>aeN}pQp22 zyWAjmJ?EOp!et=jwJw5&g1LZe)fTdoZeyZ9BgUdctpJPvRb3-u@Rh5T&$+EYj8z

67u75EdgOhNNDItI#MH&M?kKiOV4x_lyda<$e|mKHHP zS9%DUjDTE*Lw6J)IxXB>I}I0y^yqaGVc@m_qwAd9{)n(~jmFJbf|5fe*CO49?*T#j z6yo4*433AZYEY0KxL!@q=$0G~0UkG<$Y3Peh;b++nBQz8IxK-InN2N0JsJvOC z&xOM%ABro3;CY7d+ox(>U6KL6C#S0t9Ti3I4;~?9nvE^$ZB{$p-VM~kRw-OR5R;dG z63G&ik2wGO_=sSDZhyw`de^6Q7A)jn{-mtFKh4|+T&+gwme1P9rNTyt>jz3Yxs^ZQ{uP&}MG5>J8{_b~QTowL^c%8@fDOWel4)ga`^yXZ{?60(Epr!$V0hb^B7P2l$Z z1aBzht;ekd+#Nje5xq^(*P74J5xvFA43q+)>QVOujaU8kR%^71*jTMiDwl3|_^46u zUe0}j&-+F(@7{*4uJ~M5A!{|RvV86PZe|Ro{cD~!th7UT9?UPdBI13(wm~J_f7Ue;@ z`|aJNG6EON_uhc>%%?%aNJ05|5A{iW4jb%9j>UX%QAuecFWS2p)>WLlOcz3@qC4+w zrCWf}YTd3xFOXggX7#bSS^sE6*=kYVu{SWZ%%#7T=|v>EM?vY*&$c#E6OrydrcZRx zT4{QKP!M!+aRMA7k6fQtMs#@)zs7v42F1EKIbKZKb?FsRmY-#9=(;g@e&AZ`tgzb4 z=*kRG0X~qxvy0^OZs`(4pWYdM2_e%+a=nzxH9lXLY@a*WV1MiMqOARsZ{z<%*IPhU z@vZ;=bjP7XQa}zMAcAzKfHVjQ91uiAy1PL-q(Qm`q)WPy?(XjHI{fE+?!Djj```Qd ztaa9M=^AHd@7c3w@8@~F-_Q0K5RN`vbc5c{u#z0PBeoc2C=@e&SypN#xqT?7r3qb> zq4$`m>jkc0N4}4Fb2dZ-@kp_b(mM9kU+KpLJFlUhAf|W8YodI5y4$x}a_4v7NKD8- zU+mK3)Fvf?c%Y=E@cijmIGFiWy77BIWa^xnNbLf1zfQg}H~*xKKQm`jBHX9M3;HHj z;VyvWEY5e3cBAWcLcac%vtAoX1f_B=fh9?c{EiI(rz16OmU!b*2q!m)M z(@ho)JmCiou|Ch!u7tB^;%={)RSLs48bW*xHly+|Fg4LLjb{zTZeHqmo@Ew?_?EWZ zN{71iI8yS<-(Ff-os3-|-H6hD3_+0Uj4%c84TF<4k^>R1Hf)e3?Z|FF3*>0w>8>4J z$}jx}6N|+(vZoTa5$*em4~ZZHcR5M3`R5|prSC>q&K~FZ5-Fmhh*phU_q#ykJw~vx ziuq@mYKx7$!dV0}4UZ*R0oDXUfnUu7`|o7xgP=yh7P1|FW+5=euomJ{_NwgfNi;fsmq}h4Q(sDT%W1-yP_NQT73sl~= zj>BLdZI|FE$-v)%gjd`Y34=S(kW!}WB9NLOQlU)P{{w-IN8yGy0^zWrW*aChAs1FV z`4iH>B@N1csDV_>K7Z809k6=?ywU6PzldkBA8vC_7TSrn#CX~yA5jT7nagMtsmJFC zxm}F`NYCz|!~Wv)rQ2s_?<;1vs_|cyOCR1{Y^-k<=%=San$v)gOZ5BV50s#6(enj5 z_BHhk13Ye%=9DFmdu$&0q1CIA3I~Bg{aWHTR>=mgc_paSmh+u$QHpm6S?%K*Y3p!r zsYjDF9~o3Wej)GEgfG4pwpOloOI`jy95p>vxa% z-tprNVEaFg1N?GF+sxH(sf~q2Kgt)I52`P=dfMJ`rx%Tj4txNJu7X{z8Uwc~^{%*G!~#C{wonivp=cZGJ2IQV7*uk}|AGBmx=3 zK=Grc&xCHh%Q^`?D3SgwU3qlX>2OJY@eV6G!*h_lDWl7eO3l})_*`gW=8}?2+&BMr zJ0uy>P(rxpdh)V?qV=#{$(8*bCC|G7sL?Lnk=ep|+m^tbkL+cqX=Uf8%zS|Mjap;^ zo}I%@J&S1=!hl)=2wY+ldWBC|shNO8B1&8=-VGKV2*&es{rz&oeQ)6RngBIMpd^ty z`qwKebIOhd3SRTDQt1^X9&Y(6J90D3DbhM41NR3cPPZ@@`f0zn?kiNjZpAZ**Q!m) zlQ~Js=afkb9~=mI`T+zt^ zSfKSRhf1Vr?u3s|wAnMpyGCEn4E1beVI!8T=WSxW#lB0y8@$_~H*FZt*h{d-R+?3Q z*&^Fywp!5vOZ^~hAVk*rO*3n(m*^r!M>axm|Hz{a2NsppnCRRbl- z1ob3a=tJhlxIqxu@5^;<{fD48O&{&{NZQ)-HZ?UID6UwT1JENR@ z|CWV-ftjF{pa2lENZ~&?Y;roEqcifB--3G-cE~^z!<(od(Zs*&-`Mr9Jlr39Wk|Em z1&?6qn@Vcv8PMJ`X>G3ZoFIUsxB z?)~Saa6@7Mm*_!-JC_hS(|>Q(=*3xtxDHc<5&sSjy(KkWY9N8?Y=}3%O_VB_iCGg( zmob*z(YAj3sA0pT%8q}AJo~{qh1-nnm-}IOPzb__OS7efHmChB+uH(ts9NKY*e)D^ z+KLt=iSQwl*qDH^Q^uaDE+R zoW4N@=9G!Td*73}TCbLV z=^;EbxFdw19~r>uDAZ+Q8rM5z)pCK-FLX^@Lc2?qksC?-KF5CNK$H|50*_d=T2EGR zTfZDjB>V(z&LgzkNlcz?r&waR$A52WC%9_4P1Kv(ptzm-E&>x z8J(H|mDf?x2Rgkxrz8P=J(##`7189{5`Q&~Nc;)$RU7U^k5*mtX!(W8;G^H*wPbke zTkrdzWbKYeDfCC{{YRHH6 z!Y9EPsc(ZE6g!OJ8y{^HS{02{Z?+xEYB;)A>~>B@C1?55LD!Oi_Tu53^44yPu`?X) zTUXgAK@KJHK%B;(Y{QUkl!aHihO~Tmc^`ze8jeVB7BxZpveVKvNKv1GwOK;oe1h_J zVoa+&PlM+zdWpdf`VBJxDyYvT~Kd%NwS z@JK0b?}`FMDR^i4xOOHCPzuPG8_AS|~UL0MKJh50K@Mx(XrA^8R(>q=N=KNYgKmM^CC&PTS`Gtl`6!0w^E*v>Q1*yZs zd35zx;X}gkF7VguzAA_>z~4ak-k2)O$I84zxztxw0wf4q0wpksK-hswZg6H8NZJfg{=>y*qhO4gyVmvf=F&2ah#u7S zpE>&$ucUmK6F({12$Ei49?QzVFTQf_$^yetw;*Uu%W29!GsUu3pb~NU2Kh!&E}f0- zq=y42NLIh};2FPpfwsk4qA$CyYOs)*qYR9T=OZuI{BPn4tx|)&6THmGIjhPBa^n8d zt-82bW%X#98#kxxTrk{Kr^MRWZ?mnF{olZ=!7Sc*J3xF^Y;|B&OP-?c7GsfhV(Hi5 zztju)hI7Pj(JEMEuY!n+JQ3!!c`T@&3}j|Mr^-DZ@}?>^Z_$=Dm8VFCw=^toKP? z^qT z_1&VY44D$`i1ehPr&`~0HW$B?HhSO3GB@B(6Ot5Qdqy1H6X78@6Cr=gFnI|l2y9oO zwz3ah1TVW5vjF}TEpLz}(Yu3?!k_h3>Dqp4{FfO7f_2`nU-a42!~uA|^AM@|@b-L@ z7H3adz?tIm!+6X-dqQ-dw=>&m+nMo`=`hf>X~Sxz_&Vn zh6nyz9sw)rrsLMOL|t6_ft7k2AfJ*A5Trq~LM0?-WK+`0IUKEy-;4d@%mRuK(g;v- zDdQZF8(p0&7>y7it*{hva7|3OF~uq~TmnH@c?9-?c^NBv0do&YYfXz>=2T~C^WBFv z;S7p2m)|!cHPEh0-w$srXi6NfIx@Ix>Sq|>TYe47shVaLyiShP<>Xl6kV`xAv?mwOYj z0owZqOHF|vs!Wx5eU(cndr(EaTU|uV+3yfNzHO^O5+B4aVI zC^S}gO&B2UGV|Q1Cnx+}j6sp!iAX!kKn+K!%|78ic7fjo_Op!dR8|m-w@vZkH3)&C zI-*xyj({Ue>qL&R@AG1UVXMD5j4SnvpzF9tsS#7#8(|geo zDFREY+{e(dQvjJWI@V2^kUNARl0$$T>~rhTT-O38H5D><24Wn2^L@CCcD@%mEq(F{ zfS}z4dA+jPdnYa!_!d}Xd5avit{Mq4phK!y&V|oGHF#zH8iZdC{CX+q6%pV0%GANW z{U;ufM)Np9od;i9uf_P**hVwNdO9R272QR0d$P!wvB<{mD-+~Vs9)fl;3H%G;~#wQ z;k}x2=O)v0149`teSiGOHtU0)tZ>&z>euT!}?X~SKnknJO}sCtvl@3REeCw zwN)Us((RRlM(vEFR~!oz2qI{zocfT~zI=!0qIB4YO8~Lxeyon27^zGsdUCnk0c!O2 z+joPKoc|gsCt7F?C>hIIi`k@~VMG}6u@*60$OKsj*AB+szlwcz5U;U(uZl~QO+Jb5 z3vRgOU9LR#9_R%;0bQm;Yn}ncbD7YU+2Z-a&p;47LR%hGn@R7qI^yEY#>&vnk2c$H z_K@h1UTu~ht|6ArtTew=tN--eTzt?efn5hFcrCE@dfk~L!P>pR4K2i%JJq!_2MpGJ zfai}~W=SaZTr|QJ9v0DIf~)<~4cA6!GLXjJhhh+L8z1hXv1x)H8!ZPYXZ}PwQm7F3 zEu%L&dbMhS^PJf<-143aSsyQg@kN2PZSii0mJ3F%5B?Spq1LTc|1VibfV1);g<)G* z2D#T+jp@a@2uOF<{-p{nwmF+DrH!gopw+(T$0VNCYsQT7@hp-fXc}pQJv#sciJ^mn z>He9R{6T=+e{DB!Ju`qL6-eVozBcaL_&f@TeAIf_7Jq)2WS;ox@xxp2{v%q7EShK# z%5Pu8vV9}9&x#QwVzgS#BG@Y3VrZU;6nB2ek?A+WU79mFpdREXl1KTQeYPnA1~g#@ zi1`bIg%h8qnY-23gBWg|$!+soV?+z-SmriyW3l*kVmqDvTvIi66uFUCaeBp_a&YgF z*^mAQVhXFMO8xAJ?8s?LQNO0n1BSD)#dW}~;pt9o<_VQzY<9;dz~tpiqA zeb%Xs#%X97WqD}Qe*Ux4Q z@`=GhMhwN8&Q|Rn&TYs(0=%r+&B>pKb>2FWG{=zlOrrPCSTh_}Bmc0}I zWLP4`=V2V=Brvd#qA>r*oq{{VM44?gBKv*3Q|rJ3&Q6Eq`6a2PLTAGY5T@)n&Phn; z*iV7fQeyjzhr=K|p0%kZCJ6&TCx|qS1Qv%R@q`Ypm&Dav9nCATbA5RyGh6ID@aN;2 zuT3BS$1q^;vJ(4z|T1kKpk3R9m4n>u`;RX;bpBc~z3&!)w zZ)M-~}UytN#z_D5A-a(nl;b;uN$EYq&xjC$*l8Qc;?JcRgK z8>_v>m7~y7Xsdsb67W{8#_?C}Q$jQ}%=^c5o9S}8_qAbJwh)RELI?El~wEh`pLS*5$ zYCc5)Sd`jgF`k|N91jhhqnOID^>14uAgc z4uJ!NV2yO0(dqx&^M4afhV_!E<=bM3e>h+d*2syDr4QWy+XJv}8KZ#plAVMh?1Wwr7DfZTGydTDGSN-OYxp3z?q4j2kF zgJ7T^5&o$kUm+0!Hwngv&Gi4<%dlrJ#~I@LtfXb`TgTsb^eZG)GFUs$;Iz*Fp(j7U zpjuN?u449oIDi>85vWtanJxYOHQvg@I)XL)+hx~39AFH4+I@%yga0((&|&wOJ6hKK z4_NNcFxY@|fh%_TufhKBH-Lr}HXN$B$frpD;ea?i;At}BdcU#yhqsCWc8~GW9d|Gz z@4x8@K;H@ss7?5?t$%pjRsOKYJ@!RQ|L>obkGeGM%@>55YW#-*6%QM6AIP!yL;vA` zK3GS`p|&RfgVjF3n483AtpMB8s(*>R*kShTDy!~*U9sxFrC#>HKgnqHVEn_YZNiLT z5|#xg=R2A$BlC;q1Q$$*Vq;^I_woeMsO4{44pl=-;Rx{sidl_CPzn?PRIhs8J2IHq zE1UcekOvNkXV+KMskO`%bU9PL+?&iUOn_i^_4JGb#IXdh?_+3!h=*L=4~snI0FL6} zY`-_62{+9K{-zV(mi~1m97_J6H)8pUsafywcQVAZM}Fz>_-cqnQVDVKX+-pE7H2u^ zFXsU|k5E^KV{x+ApWcpo3hGy~Su9i~?M)Xc0Q^WwR-+P0B~j7)@gMtBJ^rIW_2L~; zozzeLu9%ZWYV!4WhqcQpvpxOeJjOHOET#PIpI1> z*=yI!5_}aVlb;0sk4-lv_TiLP8L4+Lga2){+$@VA@cS}m;!BhqA_{h{4Z#c9p`pm- z{K{cPKB+dKgT;|Cm+2ZSP5R~f6JBDC`BkM8290ue?;HfBdKRv6R(bR&);GNUn9S|c z80&SP>h$ydBFRQ$_xWUj-j8^^Tl(DANWjfCAY_42;|I6tTbs-M7Xjguw~;g>W!eHT zuXJ(9p@oZOF2Di!58x)80!}P_&d^&f(*aPaR*$8}m#4N4t~x88`ny7wri&`iGhp{K zR@wrUh5@JB72Y0&JL>D>^+ve-t_OAY%Oc$Qd&xuU&23vwb!L~5hXAjwSiP1k7e}%` znR6dPjH4-(*XV+oFw(A>pfhvV76=9@G5uj7Tti|*s$y*nB^g?V7K@bFD~ z=?q9VF;ec*W`dryNqUSHdVC}iGN9^G(B%k;HSmqq*9!4fNCv-e<-mxQNy>G z%z4kWKmN0Gd*7-#7gjlqK_;Jja2Eg*-TF$_TUvQ%9&nr%+qxZ(d^LA(^3zoolP6Ut zvVa+4Rl5D`--90r)c}eK4(2B!U|vY^FTY{}?zX(<$HW;h6*1dB4Z0SBNjZx}^xRdp z2$5+MX^7rw$&E@Y;Z<^qshj}t%E(PG=LRNcGuJZ)TpxpT0g9e+zH0>)kR|=g;eXB5 zG^{XQn;<(HKg8GK*h@52Ur!DQ9=ve>)qFXntG-bpu3oR+D{1ruaC{?oPTV7Rm&b2! z7k=B}4J?}sx$+h4!}}X0&Mm1`q214#D^V9a8#xXbzy&;F>^=bW;>FN6r(Ll7oz?Gv zuj*bA9?X@po;f0H?1^Vqb5#NHtopQh6HY|+YQ>~y8_knOh%Jw7i>_lW?v2N3S@2pO zfN?&T?Eo*+y?xi2zZudk5pvP{((h2f7hThSxk-v)s#Spp0Ul23g`;WCjdqd2Rg;qmDt>bvL&i#fD&o zygYbamV(zl=%{fW2Zm~PA47&G4Lcg1nRXRU=QM`m;;&p|nFV`69}{dh|0qrtzW;7} z#dt^u3e7S&t%$og7I_*2l6~lPW$AoJeHBDz&LjzDhy(e4=&I!y@^vPw9gl52=_AdL zsJq{u^oI2>?3AJNwx}2IBFa}lA)E_<68`e!BN2PK_2WjkPolQ$5@)Rp{Mfa>33FYq zH!IEa1-RzH<0hqa^JS^+6ORNyIdIY1YGF%^)&0qRly#| zfHR>uKvK%`EZ($uR~$u70xN!z^6Ga1jD39$Rx@=0o|^_0txy2L#AoU@Y%e?Qfc44F*R<^ntk zei~h50;>XvZj?&QX3!}#ahvDJNAS0u9C=N+=l0^D;4#i04__B=mjtG9WO#?e!2f*b z;ef@5wILO~rpha?w&!1`GwnvSFDWohDd%fX&rV)XWjP3ZsIdQ?@QvVLLOIrBXS&!! zVr-EVS?ZXDP3)SAP1~2du^~91Umsx)hioPi@^y)s23sVV$3h&KqLGd}j#1@epQEi9 zQ!zNwIHARIejbXqzaEYbI0tK%_$OfJutO@s?k*@rkujGPC6aJ` zt$lPM!g&7(NCIUovegCxarshFkT z6fzVu!mN_I-z75d9#NwWdo(yUs98Uv~HJOIjYKMEnDD;7QZvO(LV@kdrSKvF`>;xCTZI)fr0ml$4tVxb$w>-*( zx14GvsaAcu-Sal@T;Co4g{bGXD0>~MRYEji?#eJ#y?m(M%n;6yFE zZqEOH`u}!<*1$@<4V^1G8{C@k5J>Ivj(2k~=0^sp_m*e(L4xV^kx(@BuF&`_j#`8! z$Z5T_DT9TrC8bZ~(qD^aAhm@?6dnYqp!q>F{S_lv0q~Bml-ow zrCq<_bru?sX!5R>E~=r-SsHvmzDSZILT`rxF|^PM6tW*Y#plgX`Ll_ zeQ0)j1dwVG`k(jaX!)CH6dDLDyk~#2(i)i%YTTBwnk|KPIG;_oX#MEWuG>R=*rHXN z*D3GK@CVR-F|-){_-tC^+L|*sqI#SUI&rxziKCN}4bGsb5gyD` z2fAKRzAR2>d#cmIbHBPxxWHJ(1jO|*E@Vut1^Oy*^6_bp_`V^9uOd-AfzyAT%Bx(U zGp1&eWe63ad5_1r-T3@H=?sThoY#*U^X$y*Zuu~r&OK#SDZ;I%&QU*OHl-wv!1pc9 zigyvDj3%cdbY>z9#_k>)vnA8`N2|+ZbYhB5A6hkT1P>_lDhL8TtshyQg;F$<1B@DpIX) zE&_0DZ$p#v=nb%thKzmp0>FkQez)t?jmcu;XY7wNM(yA8BNkPva&{-#XBC*d>WE}~C8_KzOTpQqyPfhA4r4Oiq*J0cCa&Ln5-A zcD?=zH{XPBF^GXUn7A7(j~C;^(I`viyMQCar;l=H#EtcWG#)EuqtQco_wc)H>?j_np9Sc#@pLRT#>g_*5mhB=bENn zd(#1^RwO@VPXXycELV-_$(VJ!CGKmI*8cxzdiTaPEgVbA09(Tgx?X4r-e31f{Q1G< zlFZmSnDSUb*wLXChgworBB)M^l?x6s1KmUqAK|p)A~eW@K2=j{lHtj!wCZo_ai2DN zWSsbn95904KCqLNWEpH0P9qe$pAXhT(g7Nr#-&$-@L;Z5AOl-7(F7BYo&AFpd@Os& zv$9J9e-K#uroTmmWy4BSMLA172@a}kS;u8GMZuoVsl+shR* zg)_t?VIS;jwdffdXG35vE~Hr%p%S|KIenXhrYfsJDC#Y#zXthwSWUg>-!cM_rz&j) zHvKr!Pn(+h@--OO&}Le@O*6CHgB;UJL@g;*!U?N|*BOmaW%tp%bf73NlSLDB%axra z@zt&|KVvzBvoP(eR2z_I11v->DY!U1ffB2yUX^2`O3M}PqCLcNIM*VC7=QfWe&vMt z;u+yjQ7A;(t4qNn8HZ7I0Ts+ z4@uL}F(Or*Yf_!avMj-Je1-nG{}a-~A#Ax?w`bAwm7p4w8>|`{8pEMd&rwZC=gQ|_ zT^w*K5qK>!5)-i{e>7b1we){RyGkbXm3p`v~FK3jN}C;`Py}gOC<1^}9i1 z!nSBLEwl!Kck%)BZZGC9S2`?y2wo#p`O$a>ZNvHM3%|P-8?C3RTOSA1M&elh8`1l& zD`#gtM52(up~WvpjhYLFV#A9zu6Z9E=4uWR(XVd$7PMdEHaH$LTyi%*zR(-mnv&i{ zg?A8w+1=_9c4AR(b;`+d3`#%B8sWc7Yh(N{?g}`zx3(RA;4v%ELvsyNuX&16S>svW z=&GkUsm>tLgv;Cao4r`b4W|gRp4mYUc0@s|-uJ1eLR!BRXtLzxK?H0HjVsdNNJY{MA52Wv@TPMQGOK1 z)x?U5(5$<{lMprf2$({4Fi;WJMq6Jl2m*I4(C8&v3>WM2)S*=H6!jhc^Fuj=MHhF$ zv)+R41wxr~l{&g>i5x>O26v4ofP>m~ThJ~125=Cv3p>$LwzZN>Q(kV1#o*e5$36u) z`-pP4=xr=CF>wLM%1@rI=3T5BGv|o+@U={5;27kd9gjW4275y?i+2>k)FD zJm6~hGp1W*v?0_vA#i5^@N0`-Ch8ZFZF058Rwksm`55TPi0JNdvMO_7ALmcwp6N^0 zd^(2_agerRgxP)IDP~NqbmHdd@szDWSau600w<1`XpXMvN#ZL$gdlVhc#9))ng4-v z%~AJNs(qm12$^{!c6N7tD7Bs9QIm52Bsyw48vN@VB#>#8;7`)-wB(vPSG5l=Cl3*F z772eQ)UH42nQw!nuCjugM_fD)$^qdTPi>6C&(6eUDCAQykq<=ap%h3=3*%dtIn}m0 zuw>XkGu!)Fd6vOYDD+`S=>ELP)q6$LgGFWvmvJFKC(Ao-{lb0m+jFkrMBeDvpZVx57F`mDUyVZY!$O{aDr><-LANQ8o?9S%Y}^IpoLcsN`;m!^GHWYMVOZin01 zn`u~J+yO3j^)LkJ9hGvRllIA8vCdOX0?Ds^c;;BQima2?QHNjN`rwnTQs^n0Rq1yS zBfw*=y`tc?9@(d}4k+>-Gb=5Tt@8k9Exq7JPv>(q@s_u{Kh-V3T%Tp2rIeCN68L7X5~ z8*i1Lh`QCKA`jMQdh~?UODJQZHY<_X_=ORG9n@cWlm{meuaO}k;PfHo|M=T(ySpdr zrKt9VPZpeDv^aCIM1hn$0$K|Qs?IA_Uj+U#-yFk;Rr6(%n@S9gmT=0e{Ch$Kf158^ z9+6aAyHu%MnaIVghZvx5uS2<6pnkd-cLt;DGN2ivgEfjE{S8OxF?pTT{O-Ka%W5kO zuanj%z-aEvsWVR^?HQmIC3+&mlmlmP+B^Wptd0Eq#G^=@2b1|NJ^4D3OQ%6y-omGj z-ynC4^91+tuHmE4IWWL1gd_Vt)Epu(b`!epm5mkXd5JhV&z`z10FZ}j#PZdxW z{PJiZJOeh1t-%YDQt>tj1clLn!H-w-RuF@_Sam}07K~X6Q@tNC>wp9yhuQ-b`+DrQ zzc{CjXDPRL+(f>X%o9wTuFa{d14Js#}siw)u-zz=F*krD&=Ri<4olNGDDqoLq0eVT9=C>FD z?MzWrq-dxdu=Cji~PZzid?24?ZfN3c? zWR#}~kwZdY$TciCN9e=ZeF;lQ!FWlI4uudOv>Mcq&`=}Jt9_#q=vMuuIy+nWFx$hO z*X<_BYJLgoO`A{rPB4ZN0cJq(obNsYs$}d%)q$&W-z=5Q+y=V6(|4p8bslLSGs9y@ z!Ez3DIpswD66^L9wO|H&9BYgL8$Vz&PR{c&n$Y3YcK_;NDv4R+owb;#D`3nB?)N3u zDAkBuxdVk6zS(us!%hBI8Uthgin3v(QIoju_r7D>6v0GQmn;dE6IJHPNZaG?=$Oxo zTnfRMWG)M)#uHR6c+TvLK+%^as1FX&c|-4JJ`;Q%0K~tPhjUGl&{YeWk7-AixhVAZ z>9;wZU{Q}m*4nSj;VZS_zYc&faJMB&AiB<@PrbtzhIyJb3eTxu{Pqc+x_xc~CPsF< zet{8k+Qqd^4K?Qj!!c{F8N%CNFz2s?&a7>g?hYf$EV00tx^qs43KRnh@0zU!<5Kl} zniCGsqn67&S%*8RTKtmo>4ZqTYzGU{38($Ex>H!?gZvg{HA9J+BsGnD#T%}V2x9E& zsKO`~5^BQ-Uf!mko)>5YTCT-gFIG=m>;CwGOiiILfePF)-SQ}l*wW^2ZqJyjVIwu$z_=4=i_f@%WWDxix?`*=hRKa4_CtP8DlQxLqH`C5Rm}cciRjCeg{@Fl$$QijGCVO%N#VtN29&=m3wmh7 z3dEt71H>GAB^tsV#B=DoC=wwryjo9XVl2xM~Y z!6HOyp6?M9mfVz7k_A78<#=A*ZeJJ#kJ&CY$;%Wz*h`gSSc%CVyb!hG)YsTq`M_dr zj*NDHG94aIgGBVwJ(AE0s%liIUs{twMJU&+{CVv>743HXW$W*BW(4!z+)Iny35- zEp{N^#K}#MF}F+VJ!IbTJ759TYTjPp{|03@wf>qw3|kBd5AGGdm{#)Xnfu%zbZ~B~ zn&Mrx*kdv*&4ExzSJDX)^*pmOFfX?~m>%7sa*p0$L3?14a-U zh4T3%!p~MR2udikO(fE=Q<%PzK&w|a_%hNwki?#If6UaruK9h4f4>-x7?^^$oZ?y7 z@;`?|GTP{RMuE%az_;}zmb;+AR@l|suzeAi-5MaF`Dj6^l z&a)tz1V}D6RT28clTK#y(?=bq^<>C6)5097m4m#>+>mTiFl4`puMbXZ&V{B^=WyQe zAYm?jjbbxk@b;t?o=gb6C-Pm2(=K_Nb8}uBUU5?qS^&MJ7yOalTs0;H^ZuDxB!vCn0|G_OsD2Cj9w30FxXdYve8K=x!hoBr9F z3BR)V&PnhbtAdRBgRMJ{Q1RcA$`QfjZ+`(>G=xB27cC$xml53u$iC8Z$f3rSVP_vf zK!pu4-I1C1M+!5W&()JQa;W)SW4SHn#O-G8L~FOqr}G#lorOP|)oz^B)c>`(%AtpO zG|HVp+0OwLGpWPQl+H`!tZJ+~_I2ZF%YUIPAWGnJK{$*oL<|T|3{vnl6&sYO?a#-7 ze2Fhm05l88j4Mx5H3?k>9KC!?&=Vfb-VezFoSuLSM4`Z#ls;VXRFWT~rRLSB%z$5O zp<2_|J|07ge}ChlF#wjbBEol&f0XqxqQz$Yv*}8CPhSPug;ahC$ND?7sb;at?SWjg zlIG;Itw9MTJGdS@-|nHc#Yb89^nP{$PAAJBPw(PWOpf??uJFB;L2k#` z(kKWtaR2=iW`xUZ-TpI5i{=gY-@i@>0tmzKxT)=rC>+v%|5~?^Xb5j8`1q0FL2&=| z^O=!{6Bj#Z;vpsb?{flIxk-WZM@XlW3H;x?p#iy}i-Loiu2JX^|LdHvzorv-E3epX z?128~Zs3p%+2PTU%deLVKK;#USL}e6xJOV>`uz11&k>v$aS2?=A=KuRH-$Af2Q2cLt@q`}Mq-aY~QSYG_XjoVmTJ*2?~dn&zga(Xq@j}z&y)9k=Wu4G9vJNmwsxK4?vqMw1+u87(@Q{6 z^Oc@hHjCu9&+0DMEj~25ziCPrW+m!N*X)0S_D~ZFdSWz19~j^5^%s7x!HfF~r1D26 zP!4A%%2vfT7W>bjUIPO|2eMSBn96U832g1d-pemdMZV9cdS3`B!lC4~4%(aisi4R2 zQ1&$#{{FfnF!pSar?|1MDn?k1+x791u*$fDKl0mRl?%&UnGL4}mY$K``TC6WL`Gmh z1f_^rT;W7Up$4bsvOu(1u>J`^uSRfrtjfg_ zqadEUQqx~~J$;e3*ddC52~d`6bIQDk_w5m1X@&WwO7m3UCfG6#}7~g*ek`M1Y*!bZY){$7Azk}e2wD0NE zSmXnnU*#BS?3B-hgv=jOEEjHkhEjMbK0eO4zJB5F+fyFgYxYeU6vMSHty47hZ7hrr zb2nR;ufXA4TG0EEl1G(ywAYbZ`6Z(NnLMg;3yPWA+(YkX-Uy>5yE*&^`y4t_T^) z|2=j1Xeq&NyY|n2Zu`R|Eukc)PArQUIOuf+ul}kV@d{wgB`X^(sI)GPV^g1Y)YOs( zq?*hio@wwSDJBSs7l4!CxMui=z0AhbIG&bKSrA5+1ncKL;L;#YI-6w-e}rq@D9nGq z;!hf|*Rrv4iTrM9Ld4?^%VNGf#&)|;R$Jtcp;Z3fe&?N6ME6x_xt{kH4idc1H?P9U z3B>XBGl6ZzoMVzI1Cvz9bg`%B?WXXdh;@|X(bBKOt=`lh6(;?K&|mK}(H!I1^kuJ) z76BV%GXU-Bv7dW-yuZHWKL@^->@OVB6b0Ol-0uSQXuo=DFaFdZ>uE&BWOCT6{i!wj ze2VWr%vZ1BdJHgUkewTTvVrua3Xm|YnNDAA3|+Ryg*QDYc(Slq9L;-qM>EJvYri%b zt4Vh|;&Us1dri$qxKMvd$Es7Vy6>g(JF80~eoN5xfcJ2r8jy!J6*bzP|JVimIeYiy zk6Hv#rG%LzO~)F|Hv1#$VvDt^lb1dvL`SESIPnJ}F5`WfDW(*NHQ^Np0;`X3+&- zE4&zIDSyrl$8IqbzAXE6#BMFtGC2+5D%5Cr!Rz;kEJQrs66Bp7 z=xuQagbt+0K3?f4I@tW*!UMz!d^DYVN1sXP*I(r|lNL>yO=X4<^^LYdJ&IX&C-X%H zQ-l&Qyi}vQks~Y40wXCDvi*8S3syV0c+*J3!yi8=k3LT?;IPC{1cZQRp0P5>@aPXD zuRqfhG3f?LN8oIwzk1SCdtXy&@(v&i+My#2_O}=s4_WmX=vS|kIE{0(#~IB)VlnLF z*8&bW8GDn>8B?r3ewhFA0xA@r9goDLV53)@8Oywn)2gtJz#!R@Y(|iJo3}u<(9rQ| z_o{EQNd4ga^@VnM7ME*hwquyGa>+YWSX4+YRsH8umeje4PIqmJJtJX|mZ6CeIl5kp zPja=n8O|?@k`%r#8z-3*pI#=#k<3O2WQt-nCF@U`Aa1^PIGRb@o4%L(aU1S21XM2W z^h%_*`TE|OHAP??A9-s~|1G?bs~RiuM}!7GCD!y;rXgpR0%;si(Qc~PRwC+U7 zR(VWAzRs0J5alRhEsKd|GkGm7*!v+*B> z*<*Z)(%j!TAJBW6rn$evAyY)xs)|m+eC_w~AgGNZhcmdI;!haDG?&rZ7kQ+aMhnJ( zcPU#R{LeP-qUN|FACk1IErkXXo4gA(*pxQ=|3A{sGAxf}+tvy0?h*)Y!QCym27J8BQn2bpDxAFW zW@+5oJc}*7YW#>-Ne=ynD@$3K{MW_))k%?gq}S!?8sBve)epEmf})?k9Ai0}$|!FI z;SBc_K84O`m2wHdp7M~TUTEjrA*D)t5MQyY|M2|qdr z2Q$f$=am;z_zSp&k^`$>oGisAYaor@cl|8;KW_$>4wF&IN92G}bo2gld6K=ASfM6b zy+h|@8M7>L2XVExOqqs-R!+$HXH}dd46JzLYy#;H!?Wptl2O{vas%;oSu#w^4VJkq z>_Cb-wkX13lr(cxCdv4EZJhf&6Y+PhhleK2mgk2>3Y<}DwM1}-dv|iadtEC(U z{hkS@jBI(p!WBbBM6ElzP_P3qlP#9GQk!>(Jk~7cfA(-l4^IqAU~!uG z>~W5lmCBuN94%ZL9=TDWIGmmEU+qs%vu++~06jHVBsr309Y$?^27-c+DJI zqb+Q$ zkjke6e@N!o4IV6^AIfzR)AeC;gxEyo1{-xtjHOgtsgcVr>VYpy41&IRp|2-UX#nsHN-4^H+ha%336;n{)%qMvXG}1&O zAu4(c`7v&ozmi1WkQ0`L(OaZw^T@Nl@X`*RO5Bw3O_3qmZCc5h+sDTl3j_%Dy0 zQ=2CzCsCQZWY!0DRtp``wE9XtThz)9P&*^qqxumE6$|)W&ZfLgFuS(3DcY(+OZBE- zx6wan^`8Ocx5}N-7h}X-*N9u|DhKuNy~Zggaea`I31y>?Z~cSV)9-=YQT)t!n$n%) z#RmQKCY!aKTyuUz(cPeMz<*t_NJDy{Drz-uWI_X<(W_y3NWD&V=X{&)us4G`)6v2y zASBLmx+=VHylk^?B(HBG?cBT7eMYx@=rj%l@V=cqpDFh?j(6@UkgVhXz~oMiFF+d2Mg;(Y!&}^D+1qs%D^vZE z{k0OL8R$8dljh^|wg5L-ia)0c_Y&I!%8@FNNeIGZwS*D9T zu2qb2!o96^{4S(^34Os63S+n_D zL0@OVUq3%ePPVHzGan+hU^5vXF!Vr;9<64t?7{=sR^2!3{h9f)+DPR~vw5vej|j!;E!5hu_`3Lz2GllJ zHXaQah)lU0^XL>^&vmyo>2GXXMsPWMu}X7TiiW2bZMhgi725W(H{HA|+CjkM)SF@u z?2wH#9icK=U=VyOn^?ESJ0Jh>-Xm-cZ_1oS@a+hh>*Q{myWP_G4^8fKMGBo8)H2*d zqMU#Ok{Gx>?c-`>XtzsT3(eAED(?I=DD?7?V600!nGCMj<3|tWi%nP7z1t9ad7bvC zH8RNuhLNPrfflqeIOyN9%4#37&w+1ZHB+-KepGo&*~?Qn?xpzHNHGj#?ZHeTIg7=3 z8m(5N@WD(ui7iW1absx$-H$~mgZ^hoRmOwQxHJA3Ln(5l7(+j!Z5(;%!Nbh`56*+T zYdhlX>*6WzSj-jeo%{Ql6jsB(1~~dTJ5^`e95uqH6`YCoT(wUvbzCwyFN5qaS0m0n zUGmuSL}9(1v-8MffI74yELhsL2tV*`ISz;#+sDxzao0G6a>s_2VdpmaZd7S2-Z1yX zA7jfG9Nd7>`9&7G7bT=hQSU3+)fA=|V8f@FEAf$PpyP(5?<{C&fug;wOhzEl^x&$k zBwOKlh(G+GVu~z`ezjaqv2a7X!7W{oOnT#_hFZy< z@k5*1mK`29T@$*&SUrVG;Nqc}Tr-TJ8&W(vQP_cRCxyv4Aq{JA3+}H8sg20} zTAUewy1A_^sgRLF=>xB$prNT2-TiuG9FK8@8UMbCozXg6)>xWEl`5Apne-zsiV`L9ZL%>BO}}Ds_2%$ZwjpQsJM^G%*RBfcne^ zvo`Zpy7;vRv&o*Ovemlv(ofv^T2iq8@kp~4V%s%?LP1~Dlt`p4Qy>&{HVhjB{L;WM zYskIaWj?6Y<+?fE;&3^RDiEQG4T34Jt*>`UUb^m`ujvts(F=)_M;sQuJh0s+7@Y#Q zt~fKZ3H#MPGCxbn=P?V}0Fdc(3ek*5oY=L^F;JP-mx7}rt0O^yr3$mLI8!F(AMNYl z_Uw&M3rhA(98RDk2w4*70~h-Ufn^>KGQca>aSJ;3=4v&&vmBGzvtKwu_Y}udDd$`4 ztzN(Gg9Fs5y8AvCy%^}unS*Wkr4^zU#oJqw+e|Dklvz2rvS^`)YPqW_menLQn9aNA z5_wn_#V7XO^^Nf_bG&jdPd({u-S+6L^VHAgHK|o7SSPa~3NjsVLmVMdBNGpfTM*Fg z6yn0D$g(773zkw=HT_#a~L^7WgY-530n?$e)c6^zulIvj|vi$Jnh}CLN zK%YenNdTG*>-EO=4F)5^n2il~e-zPdYYLA(Dwb=nrZEAuHJRo^OZP_W01#*mN40Ou46*EDl0;oeSv5o2Aqzzhejkrh-ib8RedIdj%ekyovPu0MER@1UV;m(kg zs+b^~S@+eba*OwsxFoDWB*=q|hEf#|w|_+8;P)W1R#kq+A9@^T{DC4WfcK!5)<`w% zkN6l)lwAJ#Q?d|uU#XtVi<24;gxKw&?df` zNo-t3fd^D)DC-zo9+g@n%X%Yr_RQ-J0r)a|6n%kmZI7#?KB+!$jWCe4jTDuD(I1_T zzer>?5pkHU3LKYen~YC*znnT@!v4J6Xk;meMClP2kIGt`Z>?uP9gj>QCjiE_A=zPn zeyRVfMGrUbx>tKCzDZMRokjRJoZ*LHpL(=jMWy1n@Da!N10EB#e0fQZ0OnET`X8G=TvttCAJjK)anhX0pH zGu(Ap>sEiGLDekR(it8*Y{so6%kTpM#exdl8PH@h>w6Z1mYxwk_s7(r+{InE%TIcJCXEwu;ZyzQh2#;LH$FO*8o>3(i@ zy#R)Vc;kbHKq4F^wWBaa6l=3M%6B<9!?UTxBkQ)nJ1Yr#`aY&R6pPV}9BMQyZI81r zb>z?yYIl4#t2M~Ee)vwg8ZtQ9{N0`x)4(R$ zmfACo$9dVT@N?>SpNI(y0Wbn?7aee3k2E>LCoHA$*?ag@2cXwaT5eQmr*H^mC-bxw zE;_b%4<}!y>xqH)nQ!O2D3b16Wa7<~&1VUeG5&5EJ|eLs5^u2^qxbyBUk+Ll8By@$ z{rD4#PXn#;J@aOT_(8ft#z^@#$VZ^q=r`Kvc0QunNRJ`INO6N96AWG$&d2-Mk1Nk) zJf-^?g=SNTWMHkJs4(Ohz-b}#xuBz$?qWpb>XZXZcuZPNC0}9o*&e-a6HFKcJU5be z!Dr?%k5&$c(~_XqbD&6W#Av2yA2YxlD53!)$XGUtp^!RCaCn z5Sw%0Hu^(|T&=+@T*ja7b51?2u1UfKsxqXls|%?rV@xIYF9p#$izN{@m&Wf)vRd7v zrLx{B9PU=^ZC)F0gtlNLo<9c~pMXj|ozV|h^_~mUlX>!R?HFTj5Mu6nCXbrg z0O|~AF~x*lDywzbjCpw`@y~;puXb8`Vq!GVvaz;2MQZtsS4ZeYQz{PcwU+o3v*PMe zP_zYO8WOAMW*#v3WNC1A8DlHjGWArCI!d!W|>&p%7f%3+7A2ZS8s8<6yOcTPAxFk!FjN z=F>3;Qr4Cmq5fJj3W+2EnKvo+)=;{Fx3S?IHzm2GP(MmES@J>riJ~c+RGn+OP68~mx)$+*$mPo5TmEaC}`{gU8 zPWeX|s2TZR_vWe>wg=OZlk;s&@A_K?+xgh6pT$tv1Y^7xw&QrrF_wBDe=qp?2a$m2 zB`DrU8Yp=9{A%M7HyW&7g804h{9L`RP*+lvq&2o{^XzWD%#2r4Av!76!15LTA+;Z$ zH(c-5@03~(gWuA1AgZ(8Y-AS5>}={doc^b}EGBm-pfQeedT;H2K0iU>hn!Vb96!WX zpfHX=bj)1Qn@FnMFrC_Gafo>FNg#n}!^#QAomSB2XS&nx>Yu{l67V=^JDyoEh((6M zuwCtH)kdtkcl|OmS1wl$cgJFC0M5V^-yM;fbq4N&EjH8-)K+o4ww497PH1wuU^&9K z_>c&@lH6sP2>84?j=~1FF`yqBaW00`YUHE!E`n+=yAN~^zVStbU-Dh1M)zxWB8xK~ zBhXmQc0uwW_d$+i$zh;S3+Rz0IcyKAuB*OrV>f+Np^DPJ1fk>mCEaOT590qgZ(D3Wd*aJ3WJx0fw0tq3J0+7WrN#}V!ySBD&dYbB}Hv@{F z-IV3=>c%Cl{zKu*v{xLl`?QTRk)fMiFA-QwA5rsQl zK3k@131?KvdM5px*C>m_u_Qs8KJSTxS02^7BoiqLx_<<}x%LU>d+|sV2~QO!m&vH? z53N_O)S#sPp3Ct*=%7aRV#+1XRstpWxjH9PF1#duS5=)mMhU;s^d)u4D$EObrP*M`9+nQGuvJcBmWRi9A4b$L~N~1aX)Wwd~A|wn{F0~*}FT&;T ziN9us?@v3RxRKHZf`JUCGjY{gB9mc-vde$b$F67k;cP?WvsF4hwpBXgU{SD?;02#{ z+%^F|ivYat+<9~d>8Woz{8x%J6W>u;Kw&}`QSJ>kz*5<1uCg-_m58B?<+^UTtqFth z^bwGC3&n>TUOlIHRL8TU6L-syAj3<=99U?yu^JA=j2YrTV?41v`ztPoiNM!D!G%{{@|Sb

{Q`nd+;c=H1-&&{HJ`P@7F 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 P72r7IhH-6lCTIQ*RC@}m diff --git a/package.json b/package.json deleted file mode 100644 index 40aa86a6..00000000 --- a/package.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "activationEvents": [ - "*" - ], - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "contributes": { - "commands": [ - { - "category": "Deploy to Azure", - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline" - }, - { - "category": "Deploy to Azure", - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline" - } - ], - "configuration": { - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", - "type": "boolean" - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "default": true, - "description": "Use GitHub for creating new repository", - "type": "boolean" - } - }, - "title": "Deploy to Azure" - }, - "grammars": [ - { - "language": "yaml", - "path": "./syntaxes/yaml.tmLanguage.json", - "scopeName": "source.yaml" - } - ], - "languages": [ - { - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ], - "id": "yaml" - } - ], - "menus": { - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ], - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ] - } - }, - "dependencies": { - "fs-extra": "11.2.0", - "js-yaml": "4.1.0", - "jsonpath-plus": "9.0.0", - "mustache": "4.2.0", - "q": "2.0.3", - "semver": "7.6.3", - "shelljs": "0.8.5", - "simple-git": "3.25.0", - "tweetsodium": "0.0.6", - "typed-rest-client": "2.0.2", - "underscore": "1.13.7", - "uuid": "10.0.0", - "yaml-language-server": "1.15.0" - }, - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "devDependencies": { - "@types/fs-extra": "11.0.4", - "@types/glob": "8.1.0", - "@types/js-yaml": "4.0.9", - "@types/mustache": "4.2.5", - "@types/node": "22.5.0", - "@types/q": "1.5.8", - "@types/underscore": "1.11.15", - "ajv": "8.17.1", - "assert": "2.1.0", - "chai": "5.1.1", - "glob": "11.0.0", - "nock": "13.5.5", - "typescript-tslint-plugin": "1.0.2" - }, - "displayName": "Deploy to Azure", - "extensionDependencies": [ - "ms-vscode.azure-account" - ], - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "icon": "assets/deployToAzure.png", - "main": "./out/extension", - "name": "azure-deploy", - "scripts": { - "compile": "tsc -p ./ && node copyStaticFiles.js" - } -} diff --git a/resources/configure-cicd-pipeline.gif b/resources/configure-cicd-pipeline.gif deleted file mode 100644 index 89f0ec9c4d445db97fa54cf96175dae1dc36171e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1055754 zcmX7P2T&8;`*nH(q1Q+cNN)k@O+xR6Dj;BJ8k&TT2$~KeXp|yS6c7awG$0@#XdpBx z8k!(QLs7AysHnV(^6~qBXP()a-Mu@rcX!X-d(U$oXICdP^YB2B5AYYi0bn0t<$#m{ zK>8>kV-%426p*za6M!>ZK+X(c4*(1)1BR3XGl#%BPTw6wIfEZnrP3c5PFda@E2LlXmi0|P??BSS-DV`CFz z6B7qB6IT;c6EjmAOVc1dGX*KLBhluTmKJ6f`>?dIu(GhSy3Dnzm9*Z6tEF{diuJM6 z)+sGEz9u&57@KB^!#0O)ZEdl~&)V7A*AFlcxZI|`S_RL zlk3lCU(7BpzFd60`hT&uxVEvf!drd+>D|WL_Zx3MZGPI`{`&Lh_OGAYyMKTG-QD^7 z_s_rm`1c3BhxBsv^R>s~91Zm_VBkI-(EmZ8LI8dM`k$_Sa&&lVbd*v?Oe#SsI_qT2 z3BAa~1f}$tsOUtc)I=p`S0|;c_f$*IxF0G

3_TeAoh8KkaJ;G_fZkzS|KB> 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
)Hk1{ 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

()s#hJB>te*6J1)b#D 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 z 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 z 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 z%0D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

  • LdVDtwG>qkV5fk1l?$apkl z+zX;k&G<^rK+Qnk5XD|#GhfsPOn7BZMrXb+%3N&ET$;>W-pu?|l=;>;YtcAs4VkqW zo%Jm!>jyS-axiPfIBO0I`6|j=O;8Cc7}>y9qh|D1hyuZ~qEguylWYm^Y)wDWDJ1|; zmxQ%s1YmQ%l3^=UxF|;(pJI~TlB4k=NBc*Pu2e3;BzLEGu0c$$(ROjJaYwFB1E3|9 zL+k)B>p1~<;AMwty+8_(s<)7 z4LW3~8)BYa5Ykbg5}qI20nr8uy?>w~BR0F+Zq%iJBVO#@ryb%6@QuMA_ zPz?+nZ7)iHQIz?kh%Hr|V^W;wU0e`TTvS|qai~ZSfS&Jw#591WW+Cc?i)UldXY8PO zY9S|FW`!cMP80b+H>vY3xfxRette~{&a+no_O_JpDq~V~upF_puNd6(0<2Hq`-T(z zG9&V9Mr0ZUm#2fVpwh|WGBl$UmJLSHOJ_cm%|7^1He+{b%H$G{b{c#EUN!;x8p;H+ zL0?SDF*D$a5s{xGB3oRMK@Mc~M>$BE1F=UVXdna!gkW>{Q$hMP!ELU{uT_y-Z15Lv z5Hz*|d$D5M4kQ~3f)YS{bdc=~_|1sO_J}YB0AuJN>6ewdTa{XV6_Bn91A7oE79>aD zJ4b*(h+sI4Ly)c}n^t2PAQ-4phys$euip2v+Q|oi12r%XNNBafVXNBfV$F`r9N)_v zpRF3ICgnHWfmsbO?mBTw9^vE&8LZs6VsUtdbRLi@}0 zB5)7+mlA{Hv07{X$hhilKlc1r`s6nykBWRnna1iLN9GG5HR9uQ%|m_WS8#DJ;M#`P zRJVgtu*#$fB2Lx{eW$eT=99YwUD;`NQB6T6MtO#Wmn7XjZFPzQ@sU=OHKoyydb!*nEauhh*Vv))U3*`HKp*Y<7wSjt|fh2 z)x2`Gvy=BqVdmmTgayav$`xqe*5xbegD*oGA^D(qQeEbf_T|ggC5;Vr7d3$@1^gh11W$hp$giE5vL2(5OXW!_$_r9wJ4-={SRET(?EX61>{Ud<

    (1!EF#l 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[Tt1vdQ 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≈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 mEv0}e6(>4>n@FvckMu~A`f$GdI>_{;JCkhY diff --git a/resources/gitHubPatScope.png b/resources/gitHubPatScope.png deleted file mode 100644 index 9143feddab1d7e34841536dc9f3ce0978d36f32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84918 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

    5+_p8R-p$|+&meA+BBUB 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 { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index d88c9654..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,136 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ - -import * as path from "path"; -import * as vscode from "vscode"; -import { - AzureUserInput, - callWithTelemetryAndErrorHandling, - createTelemetryReporter, - IActionContext, - registerUIExtensionVariables, -} from "vscode-azureextensionui"; -import { - LanguageClient, - LanguageClientOptions, - ServerOptions, - TransportKind, -} from "vscode-languageclient"; -import { activateConfigurePipeline } from "./configure/activate"; -import { telemetryHelper } from "./configure/helper/telemetryHelper"; -import { extensionVariables } from "./configure/model/models"; -import { TelemetryKeys } from "./configure/resources/telemetryKeys"; -import { TracePoints } from "./configure/resources/tracePoints"; -import * as logger from "./logger"; - -const Layer = "Extension"; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling( - "azuredeploy.activate", - async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = "true"; - telemetryHelper.initialize(activateContext, "activate"); - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - await activateConfigurePipeline(); - }, TelemetryKeys.ExtensionActivationDuration); - }, - ); - - startLanguageClient(context); - - logger.log("Extension has been activated!", "ExtensionActivated"); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath( - path.join( - "node_modules", - "yaml-language-server", - "out", - "server", - "src", - "server.js", - ), - ); - - // The debug options for the server - let debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { - module: serverModule, - transport: TransportKind.ipc, - options: debugOptions, - }, - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { - language: "yaml", - pattern: "**/.github/workflows/**", - scheme: "file", - }, - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: [ - "yaml", - "http.proxy", - "http.proxyStrictSSL", - ], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher( - "**/*.?(e)y?(a)ml", - ), - ], - }, - }; - - // Create the language client and start it - let client = new LanguageClient( - "yaml", - "YAML Support", - serverOptions, - clientOptions, - ); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } catch (error) { - telemetryHelper.logError( - Layer, - TracePoints.LanguageClientActivationFailed, - error, - ); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = - vscode.window.createOutputChannel("Deploy to Azure"); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() {} diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index ebf7068a..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string) { - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} diff --git a/syntaxes/yaml.tmLanguage.json b/syntaxes/yaml.tmLanguage.json deleted file mode 100644 index c98b9811..00000000 --- a/syntaxes/yaml.tmLanguage.json +++ /dev/null @@ -1,621 +0,0 @@ -{ - "information_for_contributors": [ - "This file has been converted from https://github.com/textmate/yaml.tmbundle/blob/master/Syntaxes/YAML.tmLanguage", - "If you want to provide a fix or improvement, please create a pull request against the original repository.", - "Once accepted there, we are happy to receive an update request." - ], - "version": "https://github.com/textmate/yaml.tmbundle/commit/e54ceae3b719506dba7e481a77cea4a8b576ae46", - "name": "YAML", - "scopeName": "source.yaml", - "patterns": [ - { - "include": "#comment" - }, - { - "include": "#property" - }, - { - "include": "#directive" - }, - { - "match": "^---", - "name": "entity.other.document.begin.yaml" - }, - { - "match": "^\\.{3}", - "name": "entity.other.document.end.yaml" - }, - { - "include": "#node" - } - ], - "repository": { - "block-collection": { - "patterns": [ - { - "include": "#block-sequence" - }, - { - "include": "#block-mapping" - } - ] - }, - "block-mapping": { - "patterns": [ - { - "include": "#block-pair" - } - ] - }, - "block-node": { - "patterns": [ - { - "include": "#prototype" - }, - { - "include": "#block-scalar" - }, - { - "include": "#block-collection" - }, - { - "include": "#flow-scalar-plain-out" - }, - { - "include": "#flow-node" - } - ] - }, - "block-pair": { - "patterns": [ - { - "begin": "\\?", - "beginCaptures": { - "1": { - "name": "punctuation.definition.key-value.begin.yaml" - } - }, - "end": "(?=\\?)|^ *(:)|(:)", - "endCaptures": { - "1": { - "name": "punctuation.separator.key-value.mapping.yaml" - }, - "2": { - "name": "invalid.illegal.expected-newline.yaml" - } - }, - "name": "meta.block-mapping.yaml", - "patterns": [ - { - "include": "#block-node" - } - ] - }, - { - "begin": "(?x)\n (?=\n (?x:\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n )\n (\n [^\\s:]\n | : \\S\n | \\s+ (?![#\\s])\n )*\n \\s*\n :\n\t\t\t\t\t\t\t(\\s|$)\n )\n ", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", - "patterns": [ - { - "include": "#flow-scalar-plain-out-implicit-type" - }, - { - "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n ", - "beginCaptures": { - "0": { - "name": "entity.name.tag.yaml" - } - }, - "contentName": "entity.name.tag.yaml", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", - "name": "string.unquoted.plain.out.yaml" - } - ] - }, - { - "match": ":(?=\\s|$)", - "name": "punctuation.separator.key-value.mapping.yaml" - } - ] - }, - "block-scalar": { - "begin": "(?:(\\|)|(>))([1-9])?([-+])?(.*\\n?)", - "beginCaptures": { - "1": { - "name": "keyword.control.flow.block-scalar.literal.yaml" - }, - "2": { - "name": "keyword.control.flow.block-scalar.folded.yaml" - }, - "3": { - "name": "constant.numeric.indentation-indicator.yaml" - }, - "4": { - "name": "storage.modifier.chomping-indicator.yaml" - }, - "5": { - "patterns": [ - { - "include": "#comment" - }, - { - "match": ".+", - "name": "invalid.illegal.expected-comment-or-newline.yaml" - } - ] - } - }, - "end": "^(?=\\S)|(?!\\G)", - "patterns": [ - { - "begin": "^([ ]+)(?! )", - "end": "^(?!\\1|\\s*$)", - "name": "string.unquoted.block.yaml" - } - ] - }, - "block-sequence": { - "match": "(-)(?!\\S)", - "name": "punctuation.definition.block.sequence.item.yaml" - }, - "comment": { - "begin": "(?:(^[ \\t]*)|[ \\t]+)(?=#\\p{Print}*$)", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.yaml" - } - }, - "end": "(?!\\G)", - "patterns": [ - { - "begin": "#", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.yaml" - } - }, - "end": "\\n", - "name": "comment.line.number-sign.yaml" - } - ] - }, - "directive": { - "begin": "^%", - "beginCaptures": { - "0": { - "name": "punctuation.definition.directive.begin.yaml" - } - }, - "end": "(?=$|[ \\t]+($|#))", - "name": "meta.directive.yaml", - "patterns": [ - { - "captures": { - "1": { - "name": "keyword.other.directive.yaml.yaml" - }, - "2": { - "name": "constant.numeric.yaml-version.yaml" - } - }, - "match": "\\G(YAML)[ \\t]+(\\d+\\.\\d+)" - }, - { - "captures": { - "1": { - "name": "keyword.other.directive.tag.yaml" - }, - "2": { - "name": "storage.type.tag-handle.yaml" - }, - "3": { - "name": "support.type.tag-prefix.yaml" - } - }, - "match": "(?x)\n \\G\n (TAG)\n (?:[ \\t]+\n ((?:!(?:[0-9A-Za-z\\-]*!)?))\n (?:[ \\t]+ (\n ! (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )*\n | (?![,!\\[\\]{}]) (?x: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+\n )\n )?\n )?\n " - }, - { - "captures": { - "1": { - "name": "support.other.directive.reserved.yaml" - }, - "2": { - "name": "string.unquoted.directive-name.yaml" - }, - "3": { - "name": "string.unquoted.directive-parameter.yaml" - } - }, - "match": "(?x) \\G (\\w+) (?:[ \\t]+ (\\w+) (?:[ \\t]+ (\\w+))? )?" - }, - { - "match": "\\S+", - "name": "invalid.illegal.unrecognized.yaml" - } - ] - }, - "flow-alias": { - "captures": { - "1": { - "name": "keyword.control.flow.alias.yaml" - }, - "2": { - "name": "punctuation.definition.alias.yaml" - }, - "3": { - "name": "variable.other.alias.yaml" - }, - "4": { - "name": "invalid.illegal.character.anchor.yaml" - } - }, - "match": "((\\*))([^\\s\\[\\]/{/},]+)([^\\s\\]},]\\S*)?" - }, - "flow-collection": { - "patterns": [ - { - "include": "#flow-sequence" - }, - { - "include": "#flow-mapping" - } - ] - }, - "flow-mapping": { - "begin": "\\{", - "beginCaptures": { - "0": { - "name": "punctuation.definition.mapping.begin.yaml" - } - }, - "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.mapping.end.yaml" - } - }, - "name": "meta.flow-mapping.yaml", - "patterns": [ - { - "include": "#prototype" - }, - { - "match": ",", - "name": "punctuation.separator.mapping.yaml" - }, - { - "include": "#flow-pair" - } - ] - }, - "flow-node": { - "patterns": [ - { - "include": "#prototype" - }, - { - "include": "#flow-alias" - }, - { - "include": "#flow-collection" - }, - { - "include": "#flow-scalar" - } - ] - }, - "flow-pair": { - "patterns": [ - { - "begin": "\\?", - "beginCaptures": { - "0": { - "name": "punctuation.definition.key-value.begin.yaml" - } - }, - "end": "(?=[},\\]])", - "name": "meta.flow-pair.explicit.yaml", - "patterns": [ - { - "include": "#prototype" - }, - { - "include": "#flow-pair" - }, - { - "include": "#flow-node" - }, - { - "begin": ":(?=\\s|$|[\\[\\]{},])", - "beginCaptures": { - "0": { - "name": "punctuation.separator.key-value.mapping.yaml" - } - }, - "end": "(?=[},\\]])", - "patterns": [ - { - "include": "#flow-value" - } - ] - } - ] - }, - { - "begin": "(?x)\n (?=\n (?:\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n )\n (\n [^\\s:[\\[\\]{},]]\n | : [^\\s[\\[\\]{},]]\n | \\s+ (?![#\\s])\n )*\n \\s*\n :\n\t\t\t\t\t\t\t(\\s|$)\n )\n ", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", - "name": "meta.flow-pair.key.yaml", - "patterns": [ - { - "include": "#flow-scalar-plain-in-implicit-type" - }, - { - "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n ", - "beginCaptures": { - "0": { - "name": "entity.name.tag.yaml" - } - }, - "contentName": "entity.name.tag.yaml", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", - "name": "string.unquoted.plain.in.yaml" - } - ] - }, - { - "include": "#flow-node" - }, - { - "begin": ":(?=\\s|$|[\\[\\]{},])", - "captures": { - "0": { - "name": "punctuation.separator.key-value.mapping.yaml" - } - }, - "end": "(?=[},\\]])", - "name": "meta.flow-pair.yaml", - "patterns": [ - { - "include": "#flow-value" - } - ] - } - ] - }, - "flow-scalar": { - "patterns": [ - { - "include": "#flow-scalar-double-quoted" - }, - { - "include": "#flow-scalar-single-quoted" - }, - { - "include": "#flow-scalar-plain-in" - } - ] - }, - "flow-scalar-double-quoted": { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.yaml" - } - }, - "end": "\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.yaml" - } - }, - "name": "string.quoted.double.yaml", - "patterns": [ - { - "match": "\\\\([0abtnvfre \"/\\\\N_Lp]|x\\d\\d|u\\d{4}|U\\d{8})", - "name": "constant.character.escape.yaml" - }, - { - "match": "\\\\\\n", - "name": "constant.character.escape.double-quoted.newline.yaml" - } - ] - }, - "flow-scalar-plain-in": { - "patterns": [ - { - "include": "#flow-scalar-plain-in-implicit-type" - }, - { - "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] [^\\s[\\[\\]{},]]\n ", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n ", - "name": "string.unquoted.plain.in.yaml" - } - ] - }, - "flow-scalar-plain-in-implicit-type": { - "patterns": [ - { - "captures": { - "1": { - "name": "constant.language.null.yaml" - }, - "2": { - "name": "constant.language.boolean.yaml" - }, - "3": { - "name": "constant.numeric.integer.yaml" - }, - "4": { - "name": "constant.numeric.float.yaml" - }, - "5": { - "name": "constant.other.timestamp.yaml" - }, - "6": { - "name": "constant.language.value.yaml" - }, - "7": { - "name": "constant.language.merge.yaml" - } - }, - "match": "(?x)\n (?x:\n (null|Null|NULL|~)\n | (y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)\n | (\n (?:\n [-+]? 0b [0-1_]+ # (base 2)\n | [-+]? 0 [0-7_]+ # (base 8)\n | [-+]? (?: 0|[1-9][0-9_]*) # (base 10)\n | [-+]? 0x [0-9a-fA-F_]+ # (base 16)\n | [-+]? [1-9] [0-9_]* (?: :[0-5]?[0-9])+ # (base 60)\n )\n )\n | (\n (?x:\n [-+]? (?: [0-9] [0-9_]*)? \\. [0-9.]* (?: [eE] [-+] [0-9]+)? # (base 10)\n | [-+]? [0-9] [0-9_]* (?: :[0-5]?[0-9])+ \\. [0-9_]* # (base 60)\n | [-+]? \\. (?: inf|Inf|INF) # (infinity)\n | \\. (?: nan|NaN|NAN) # (not a number)\n )\n )\n | (\n (?x:\n \\d{4} - \\d{2} - \\d{2} # (y-m-d)\n | \\d{4} # (year)\n - \\d{1,2} # (month)\n - \\d{1,2} # (day)\n (?: [Tt] | [ \\t]+) \\d{1,2} # (hour)\n : \\d{2} # (minute)\n : \\d{2} # (second)\n (?: \\.\\d*)? # (fraction)\n (?:\n (?:[ \\t]*) Z\n | [-+] \\d{1,2} (?: :\\d{1,2})?\n )? # (time zone)\n )\n )\n | (=)\n | (<<)\n )\n (?:\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n | \\s* : [\\[\\]{},]\n | \\s* [\\[\\]{},]\n )\n )\n " - } - ] - }, - "flow-scalar-plain-out": { - "patterns": [ - { - "include": "#flow-scalar-plain-out-implicit-type" - }, - { - "begin": "(?x)\n [^\\s[-?:,\\[\\]{}#&*!|>'\"%@`]]\n | [?:-] \\S\n ", - "end": "(?x)\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n ", - "name": "string.unquoted.plain.out.yaml" - } - ] - }, - "flow-scalar-plain-out-implicit-type": { - "patterns": [ - { - "captures": { - "1": { - "name": "constant.language.null.yaml" - }, - "2": { - "name": "constant.language.boolean.yaml" - }, - "3": { - "name": "constant.numeric.integer.yaml" - }, - "4": { - "name": "constant.numeric.float.yaml" - }, - "5": { - "name": "constant.other.timestamp.yaml" - }, - "6": { - "name": "constant.language.value.yaml" - }, - "7": { - "name": "constant.language.merge.yaml" - } - }, - "match": "(?x)\n (?x:\n (null|Null|NULL|~)\n | (y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)\n | (\n (?:\n [-+]? 0b [0-1_]+ # (base 2)\n | [-+]? 0 [0-7_]+ # (base 8)\n | [-+]? (?: 0|[1-9][0-9_]*) # (base 10)\n | [-+]? 0x [0-9a-fA-F_]+ # (base 16)\n | [-+]? [1-9] [0-9_]* (?: :[0-5]?[0-9])+ # (base 60)\n )\n )\n | (\n (?x:\n [-+]? (?: [0-9] [0-9_]*)? \\. [0-9.]* (?: [eE] [-+] [0-9]+)? # (base 10)\n | [-+]? [0-9] [0-9_]* (?: :[0-5]?[0-9])+ \\. [0-9_]* # (base 60)\n | [-+]? \\. (?: inf|Inf|INF) # (infinity)\n | \\. (?: nan|NaN|NAN) # (not a number)\n )\n )\n | (\n (?x:\n \\d{4} - \\d{2} - \\d{2} # (y-m-d)\n | \\d{4} # (year)\n - \\d{1,2} # (month)\n - \\d{1,2} # (day)\n (?: [Tt] | [ \\t]+) \\d{1,2} # (hour)\n : \\d{2} # (minute)\n : \\d{2} # (second)\n (?: \\.\\d*)? # (fraction)\n (?:\n (?:[ \\t]*) Z\n | [-+] \\d{1,2} (?: :\\d{1,2})?\n )? # (time zone)\n )\n )\n | (=)\n | (<<)\n )\n (?x:\n (?=\n \\s* $\n | \\s+ \\#\n | \\s* : (\\s|$)\n )\n )\n " - } - ] - }, - "flow-scalar-single-quoted": { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.yaml" - } - }, - "end": "'(?!')", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.yaml" - } - }, - "name": "string.quoted.single.yaml", - "patterns": [ - { - "match": "''", - "name": "constant.character.escape.single-quoted.yaml" - } - ] - }, - "flow-sequence": { - "begin": "\\[", - "beginCaptures": { - "0": { - "name": "punctuation.definition.sequence.begin.yaml" - } - }, - "end": "\\]", - "endCaptures": { - "0": { - "name": "punctuation.definition.sequence.end.yaml" - } - }, - "name": "meta.flow-sequence.yaml", - "patterns": [ - { - "include": "#prototype" - }, - { - "match": ",", - "name": "punctuation.separator.sequence.yaml" - }, - { - "include": "#flow-pair" - }, - { - "include": "#flow-node" - } - ] - }, - "flow-value": { - "patterns": [ - { - "begin": "\\G(?![},\\]])", - "end": "(?=[},\\]])", - "name": "meta.flow-pair.value.yaml", - "patterns": [ - { - "include": "#flow-node" - } - ] - } - ] - }, - "node": { - "patterns": [ - { - "include": "#block-node" - } - ] - }, - "property": { - "begin": "(?=!|&)", - "end": "(?!\\G)", - "name": "meta.property.yaml", - "patterns": [ - { - "captures": { - "1": { - "name": "keyword.control.property.anchor.yaml" - }, - "2": { - "name": "punctuation.definition.anchor.yaml" - }, - "3": { - "name": "entity.name.type.anchor.yaml" - }, - "4": { - "name": "invalid.illegal.character.anchor.yaml" - } - }, - "match": "\\G((&))([^\\s\\[\\]/{/},]+)(\\S+)?" - }, - { - "match": "(?x)\n \\G\n (?:\n ! < (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$,_.!~*'()\\[\\]] )+ >\n | (?:!(?:[0-9A-Za-z\\-]*!)?) (?: %[0-9A-Fa-f]{2} | [0-9A-Za-z\\-#;/?:@&=+$_.~*'()] )+\n | !\n )\n (?=\\ |\\t|$)\n ", - "name": "storage.type.tag-handle.yaml" - }, - { - "match": "\\S+", - "name": "invalid.illegal.tag-handle.yaml" - } - ] - }, - "prototype": { - "patterns": [ - { - "include": "#comment" - }, - { - "include": "#property" - } - ] - } - } -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index f37a4f03..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "compilerOptions": { - /* Parse in strict mode and emit "use strict" for each source file. */ - "alwaysStrict": true, - - /* List of library files to be included in the compilation. */ - "lib": ["es6"], - - /* Specify module code generation. */ - "module": "commonjs", - - /* */ - "moduleResolution": "node", - - /* Report errors for fallthrough cases in switch statement. */ - "noFallthroughCasesInSwitch": true, - - /* Report error when not all code paths in function return a value. */ - "noImplicitReturns": true, - - /* Report errors on unused locals. */ - "noUnusedLocals": true, - - /* Report errors on unused parameters. */ - //"noUnusedParameters": true, - - /* Redirect output structure to the directory. */ - "outDir": "out", - - /* Specifies the root directory of input files. Only use to control the output directory structure with --outDir. */ - "rootDir": "src", - - /* Generates corresponding .map file. */ - "sourceMap": true, - - /* Enable all strict type checking options. - Enabling --strict enables - --noImplicitAny, - --noImplicitThis, - --alwaysStrict, - --strictNullChecks, - --strictFunctionTypes - --strictPropertyInitialization. - */ - //"strict": true, - - /* Specify ECMAScript target version. */ - "target": "es6", - - /* */ - "allowJs": true, - - "plugins": [ - { - "name": "typescript-tslint-plugin" - } - ] - }, - "include": ["src/**/*", "src/credentialstore/bin/win32/creds.exe"], - "exclude": ["node_modules", ".vscode-test", "tools/**"] -} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index ec10dc13..00000000 --- a/tslint.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], - "rules": { - "no-string-throw": true, - "no-unused-expression": true, - "no-duplicate-variable": true, - "curly": true, - "class-name": true, - "semicolon": [true, "always"], - "triple-equals": false, - "no-banned-terms": true, - "no-delete-expression": true, - "no-document-domain": true, - "no-disable-auto-sanitization": true, - "no-duplicate-parameter-names": true, - "no-exec-script": true, - "no-function-constructor-with-string-args": true, - "no-octal-literal": true, - "no-reserved-keywords": true, - "no-string-based-set-immediate": true, - "no-string-based-set-interval": true, - "no-string-based-set-timeout": true, - "no-eval": true, - "quotemark": false, - "no-relative-imports": false, - "max-line-length": [ - true, - { - "limit": 135, - "ignore-pattern": "^import [^,]+ from |^export | implements" - } - ], - "trailing-comma": false, - "one-line": false, - "ordered-imports": [ - true, - { - "import-sources-order": "case-insensitive", - "named-imports-order": "case-insensitive" - } - ], - "no-constant-condition": [ - true, - { - "checkLoops": false - } - ], - "no-angle-bracket-type-assertion": false, - "object-literal-sort-keys": false, - "prefer-type-cast": false, - "function-name": false, - "max-classes-per-file": false, - "no-backbone-get-set-outside-model": false, - "non-literal-fs-path": false - }, - "defaultSeverity": "warning", - "extends": ["tslint-microsoft-contrib/recommended", "tslint:recommended"] -} From 6ee4d2345aa0bbedb0176faf7d31b1bf9f0c6c77 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 10 Sep 2024 03:21:04 +0300 Subject: [PATCH 93/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - {src => Source}/configure/activate.ts | 0 {src => Source}/configure/browse.ts | 0 .../clients/IProvisioningServiceClient.ts | 0 .../clients/ITemplateServiceClient.ts | 0 .../clients/ProvisioningServiceClient.ts | 0 .../clients/TemplateServiceClientFactory.ts | 0 .../clients/azure/appServiceClient.ts | 0 .../configure/clients/azure/armRestClient.ts | 0 .../clients/azure/azureResourceClient.ts | 0 .../clients/devOps/azureDevOpsClient.ts | 0 .../clients/devOps/serviceConnectionClient.ts | 0 .../clients/github/TemplateServiceClient.ts | 0 .../configure/clients/github/githubClient.ts | 0 .../clients/modaRepositoryAnalysisClient.ts | 0 ...portalExtensionRepositoryAnalysisClient.ts | 0 .../provisioningServiceClientFactory.ts | 0 .../clients/repositoryAnalyisClient.ts | 0 .../configure/clients/restClient.ts | 0 {src => Source}/configure/configure.ts | 0 .../configurers/AksAzureResourceSelector.ts | 0 .../configurers/IAzureResourceSelector.ts | 0 .../configurers/IProvisioningConfigurer.ts | 0 .../configurers/ResourceSelectorFactory.ts | 0 .../WebAppAzureResourceSelector.ts | 0 .../configurers/azurePipelineConfigurer.ts | 0 .../configure/configurers/configurerBase.ts | 0 .../configurers/configurerFactory.ts | 0 .../localGithubWorkflowConfigurer.ts | 0 .../configurers/provisioningConfigurer.ts | 0 .../remoteGitHubWorkflowConfigurer.ts | 0 .../configure/helper/AssetHandler.ts | 0 .../configure/helper/DataSourceHandler.ts | 0 .../configure/helper/LocalGitRepoHelper.ts | 0 .../configure/helper/azureSessionHelper.ts | 0 .../configure/helper/commonHelper.ts | 0 .../configure/helper/controlProvider.ts | 0 .../helper/devOps/azureDevOpsHelper.ts | 0 .../helper/devOps/serviceConnectionHelper.ts | 0 .../configure/helper/gitHubHelper.ts | 0 .../configure/helper/graphHelper.ts | 0 .../configure/helper/mustacheHelper.ts | 0 .../helper/remoteServiceUrlHelper.ts | 0 .../configure/helper/repoAnalysisHelper.ts | 0 .../helper/sodium/SodiumLibHelper.ts | 0 .../configure/helper/sodium/sodium.d.ts | 0 .../configure/helper/telemetryHelper.ts | 0 .../configure/helper/templateHelper.ts | 0 .../helper/templateParameterHelper.ts | 0 {src => Source}/configure/model/Contracts.ts | 0 .../configure/model/azureDevOps.ts | 0 {src => Source}/configure/model/models.ts | 0 .../model/provisioningConfiguration.ts | 0 .../configure/model/templateModels.ts | 0 .../configure/resources/constants.ts | 0 .../configure/resources/messages.ts | 0 .../configure/resources/telemetryKeys.ts | 0 .../configure/resources/tracePoints.ts | 0 .../templateInputHelper/InputControl.ts | 0 .../InputControlProvider.ts | 0 .../RepoAnalysisSettingInputProvider.ts | 0 .../utilities/DataSourceExpression.ts | 0 .../utilities/DataSourceUtility.ts | 0 .../utilities/InputControlUtility.ts | 0 .../utilities/VisibilityHelper.ts | 0 .../utilities/validation/StaticValidator.ts | 0 .../dotnetcoreLinuxFunctionApp.yml | 0 .../dotnetcoreLinuxWebApp.yml | 0 .../dotnetcoreWindowsFunctionApp.yml | 0 .../dotnetcoreWindowsWebApp.yml | 0 .../azurePipelineTemplates/nodejs.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../nodejsLinuxWebApp.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngular.yml | 0 .../nodejsWithAngularLinuxWebApp.yml | 0 .../nodejsWithGrunt.yml | 0 .../nodejsWithGruntLinuxWebApp.yml | 0 .../azurePipelineTemplates/nodejsWithGulp.yml | 0 .../nodejsWithGulpLinuxWebApp.yml | 0 .../nodejsWithWebpack.yml | 0 .../nodejsWithWebpackLinuxWebApp.yml | 0 .../azurePipelineTemplates/pythonDjango.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../simpleLinuxWebApp.yml | 0 .../azurePipelineTemplates/simpleWebApp.yml | 0 .../templates/dependencies/deployment.yml | 0 .../templates/dependencies/ingress.yml | 0 .../dependencies/service-ingress.yml | 0 .../templates/dependencies/service.yml | 0 .../AksWithReuseACR.yml | 0 .../nodejsLinuxFunctionApp.yml | 0 .../githubWorkflowTemplates/nodejsOnLinux.yml | 0 .../nodejsOnWindows.yml | 0 .../nodejsWindowsFunctionApp.yml | 0 .../nodejsWithAngularOnLinuxWebApp.yml | 0 .../nodejsWithAngularOnWindowsWebApp.yml | 0 .../nodejsWithGruntOnLinuxWebApp.yml | 0 .../nodejsWithGruntOnWindowsWebApp.yml | 0 .../nodejsWithGulpOnLinuxWebApp.yml | 0 .../nodejsWithGulpOnWindowsWebApp.yml | 0 .../nodejsWithWebpackOnLinuxWebApp.yml | 0 .../nodejsWithWebpackOnWindowsWebApp.yml | 0 .../pythonLinuxFunctionApp.yml | 0 .../pythonLinuxWebApp.yml | 0 .../githubWorkflowTemplates/simpleWebApp.yml | 0 .../configure/utilities/templateConverter.ts | 0 .../configure/utilities/utilities.ts | 0 .../utilities/webAppNodeVersionConverter.ts | 0 {src => Source}/extension.ts | 0 {src => Source}/logger.ts | 0 package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - 131 files changed, 116 insertions(+), 9128 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json rename {src => Source}/configure/activate.ts (100%) rename {src => Source}/configure/browse.ts (100%) rename {src => Source}/configure/clients/IProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/ITemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/ProvisioningServiceClient.ts (100%) rename {src => Source}/configure/clients/TemplateServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/azure/appServiceClient.ts (100%) rename {src => Source}/configure/clients/azure/armRestClient.ts (100%) rename {src => Source}/configure/clients/azure/azureResourceClient.ts (100%) rename {src => Source}/configure/clients/devOps/azureDevOpsClient.ts (100%) rename {src => Source}/configure/clients/devOps/serviceConnectionClient.ts (100%) rename {src => Source}/configure/clients/github/TemplateServiceClient.ts (100%) rename {src => Source}/configure/clients/github/githubClient.ts (100%) rename {src => Source}/configure/clients/modaRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/portalExtensionRepositoryAnalysisClient.ts (100%) rename {src => Source}/configure/clients/provisioningServiceClientFactory.ts (100%) rename {src => Source}/configure/clients/repositoryAnalyisClient.ts (100%) rename {src => Source}/configure/clients/restClient.ts (100%) rename {src => Source}/configure/configure.ts (100%) rename {src => Source}/configure/configurers/AksAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/IProvisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/ResourceSelectorFactory.ts (100%) rename {src => Source}/configure/configurers/WebAppAzureResourceSelector.ts (100%) rename {src => Source}/configure/configurers/azurePipelineConfigurer.ts (100%) rename {src => Source}/configure/configurers/configurerBase.ts (100%) rename {src => Source}/configure/configurers/configurerFactory.ts (100%) rename {src => Source}/configure/configurers/localGithubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/configurers/provisioningConfigurer.ts (100%) rename {src => Source}/configure/configurers/remoteGitHubWorkflowConfigurer.ts (100%) rename {src => Source}/configure/helper/AssetHandler.ts (100%) rename {src => Source}/configure/helper/DataSourceHandler.ts (100%) rename {src => Source}/configure/helper/LocalGitRepoHelper.ts (100%) rename {src => Source}/configure/helper/azureSessionHelper.ts (100%) rename {src => Source}/configure/helper/commonHelper.ts (100%) rename {src => Source}/configure/helper/controlProvider.ts (100%) rename {src => Source}/configure/helper/devOps/azureDevOpsHelper.ts (100%) rename {src => Source}/configure/helper/devOps/serviceConnectionHelper.ts (100%) rename {src => Source}/configure/helper/gitHubHelper.ts (100%) rename {src => Source}/configure/helper/graphHelper.ts (100%) rename {src => Source}/configure/helper/mustacheHelper.ts (100%) rename {src => Source}/configure/helper/remoteServiceUrlHelper.ts (100%) rename {src => Source}/configure/helper/repoAnalysisHelper.ts (100%) rename {src => Source}/configure/helper/sodium/SodiumLibHelper.ts (100%) rename {src => Source}/configure/helper/sodium/sodium.d.ts (100%) rename {src => Source}/configure/helper/telemetryHelper.ts (100%) rename {src => Source}/configure/helper/templateHelper.ts (100%) rename {src => Source}/configure/helper/templateParameterHelper.ts (100%) rename {src => Source}/configure/model/Contracts.ts (100%) rename {src => Source}/configure/model/azureDevOps.ts (100%) rename {src => Source}/configure/model/models.ts (100%) rename {src => Source}/configure/model/provisioningConfiguration.ts (100%) rename {src => Source}/configure/model/templateModels.ts (100%) rename {src => Source}/configure/resources/constants.ts (100%) rename {src => Source}/configure/resources/messages.ts (100%) rename {src => Source}/configure/resources/telemetryKeys.ts (100%) rename {src => Source}/configure/resources/tracePoints.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControl.ts (100%) rename {src => Source}/configure/templateInputHelper/InputControlProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceExpression.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/DataSourceUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/InputControlUtility.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/VisibilityHelper.ts (100%) rename {src => Source}/configure/templateInputHelper/utilities/validation/StaticValidator.ts (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejs.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonDjango.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/azurePipelineTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/templates/dependencies/deployment.yml (100%) rename {src => Source}/configure/templates/dependencies/ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service-ingress.yml (100%) rename {src => Source}/configure/templates/dependencies/service.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml (100%) rename {src => Source}/configure/templates/githubWorkflowTemplates/simpleWebApp.yml (100%) rename {src => Source}/configure/utilities/templateConverter.ts (100%) rename {src => Source}/configure/utilities/utilities.ts (100%) rename {src => Source}/configure/utilities/webAppNodeVersionConverter.ts (100%) rename {src => Source}/extension.ts (100%) rename {src => Source}/logger.ts (100%) delete mode 100644 package-lock.json delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/src/configure/activate.ts b/Source/configure/activate.ts similarity index 100% rename from src/configure/activate.ts rename to Source/configure/activate.ts diff --git a/src/configure/browse.ts b/Source/configure/browse.ts similarity index 100% rename from src/configure/browse.ts rename to Source/configure/browse.ts diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/Source/configure/clients/IProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/IProvisioningServiceClient.ts rename to Source/configure/clients/IProvisioningServiceClient.ts diff --git a/src/configure/clients/ITemplateServiceClient.ts b/Source/configure/clients/ITemplateServiceClient.ts similarity index 100% rename from src/configure/clients/ITemplateServiceClient.ts rename to Source/configure/clients/ITemplateServiceClient.ts diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/Source/configure/clients/ProvisioningServiceClient.ts similarity index 100% rename from src/configure/clients/ProvisioningServiceClient.ts rename to Source/configure/clients/ProvisioningServiceClient.ts diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/Source/configure/clients/TemplateServiceClientFactory.ts similarity index 100% rename from src/configure/clients/TemplateServiceClientFactory.ts rename to Source/configure/clients/TemplateServiceClientFactory.ts diff --git a/src/configure/clients/azure/appServiceClient.ts b/Source/configure/clients/azure/appServiceClient.ts similarity index 100% rename from src/configure/clients/azure/appServiceClient.ts rename to Source/configure/clients/azure/appServiceClient.ts diff --git a/src/configure/clients/azure/armRestClient.ts b/Source/configure/clients/azure/armRestClient.ts similarity index 100% rename from src/configure/clients/azure/armRestClient.ts rename to Source/configure/clients/azure/armRestClient.ts diff --git a/src/configure/clients/azure/azureResourceClient.ts b/Source/configure/clients/azure/azureResourceClient.ts similarity index 100% rename from src/configure/clients/azure/azureResourceClient.ts rename to Source/configure/clients/azure/azureResourceClient.ts diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/Source/configure/clients/devOps/azureDevOpsClient.ts similarity index 100% rename from src/configure/clients/devOps/azureDevOpsClient.ts rename to Source/configure/clients/devOps/azureDevOpsClient.ts diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/Source/configure/clients/devOps/serviceConnectionClient.ts similarity index 100% rename from src/configure/clients/devOps/serviceConnectionClient.ts rename to Source/configure/clients/devOps/serviceConnectionClient.ts diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/Source/configure/clients/github/TemplateServiceClient.ts similarity index 100% rename from src/configure/clients/github/TemplateServiceClient.ts rename to Source/configure/clients/github/TemplateServiceClient.ts diff --git a/src/configure/clients/github/githubClient.ts b/Source/configure/clients/github/githubClient.ts similarity index 100% rename from src/configure/clients/github/githubClient.ts rename to Source/configure/clients/github/githubClient.ts diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/Source/configure/clients/modaRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/modaRepositoryAnalysisClient.ts rename to Source/configure/clients/modaRepositoryAnalysisClient.ts diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts similarity index 100% rename from src/configure/clients/portalExtensionRepositoryAnalysisClient.ts rename to Source/configure/clients/portalExtensionRepositoryAnalysisClient.ts diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/Source/configure/clients/provisioningServiceClientFactory.ts similarity index 100% rename from src/configure/clients/provisioningServiceClientFactory.ts rename to Source/configure/clients/provisioningServiceClientFactory.ts diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/Source/configure/clients/repositoryAnalyisClient.ts similarity index 100% rename from src/configure/clients/repositoryAnalyisClient.ts rename to Source/configure/clients/repositoryAnalyisClient.ts diff --git a/src/configure/clients/restClient.ts b/Source/configure/clients/restClient.ts similarity index 100% rename from src/configure/clients/restClient.ts rename to Source/configure/clients/restClient.ts diff --git a/src/configure/configure.ts b/Source/configure/configure.ts similarity index 100% rename from src/configure/configure.ts rename to Source/configure/configure.ts diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/Source/configure/configurers/AksAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/AksAzureResourceSelector.ts rename to Source/configure/configurers/AksAzureResourceSelector.ts diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/Source/configure/configurers/IAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/IAzureResourceSelector.ts rename to Source/configure/configurers/IAzureResourceSelector.ts diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/Source/configure/configurers/IProvisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/IProvisioningConfigurer.ts rename to Source/configure/configurers/IProvisioningConfigurer.ts diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/Source/configure/configurers/ResourceSelectorFactory.ts similarity index 100% rename from src/configure/configurers/ResourceSelectorFactory.ts rename to Source/configure/configurers/ResourceSelectorFactory.ts diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/Source/configure/configurers/WebAppAzureResourceSelector.ts similarity index 100% rename from src/configure/configurers/WebAppAzureResourceSelector.ts rename to Source/configure/configurers/WebAppAzureResourceSelector.ts diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/Source/configure/configurers/azurePipelineConfigurer.ts similarity index 100% rename from src/configure/configurers/azurePipelineConfigurer.ts rename to Source/configure/configurers/azurePipelineConfigurer.ts diff --git a/src/configure/configurers/configurerBase.ts b/Source/configure/configurers/configurerBase.ts similarity index 100% rename from src/configure/configurers/configurerBase.ts rename to Source/configure/configurers/configurerBase.ts diff --git a/src/configure/configurers/configurerFactory.ts b/Source/configure/configurers/configurerFactory.ts similarity index 100% rename from src/configure/configurers/configurerFactory.ts rename to Source/configure/configurers/configurerFactory.ts diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/Source/configure/configurers/localGithubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/localGithubWorkflowConfigurer.ts rename to Source/configure/configurers/localGithubWorkflowConfigurer.ts diff --git a/src/configure/configurers/provisioningConfigurer.ts b/Source/configure/configurers/provisioningConfigurer.ts similarity index 100% rename from src/configure/configurers/provisioningConfigurer.ts rename to Source/configure/configurers/provisioningConfigurer.ts diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts similarity index 100% rename from src/configure/configurers/remoteGitHubWorkflowConfigurer.ts rename to Source/configure/configurers/remoteGitHubWorkflowConfigurer.ts diff --git a/src/configure/helper/AssetHandler.ts b/Source/configure/helper/AssetHandler.ts similarity index 100% rename from src/configure/helper/AssetHandler.ts rename to Source/configure/helper/AssetHandler.ts diff --git a/src/configure/helper/DataSourceHandler.ts b/Source/configure/helper/DataSourceHandler.ts similarity index 100% rename from src/configure/helper/DataSourceHandler.ts rename to Source/configure/helper/DataSourceHandler.ts diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/Source/configure/helper/LocalGitRepoHelper.ts similarity index 100% rename from src/configure/helper/LocalGitRepoHelper.ts rename to Source/configure/helper/LocalGitRepoHelper.ts diff --git a/src/configure/helper/azureSessionHelper.ts b/Source/configure/helper/azureSessionHelper.ts similarity index 100% rename from src/configure/helper/azureSessionHelper.ts rename to Source/configure/helper/azureSessionHelper.ts diff --git a/src/configure/helper/commonHelper.ts b/Source/configure/helper/commonHelper.ts similarity index 100% rename from src/configure/helper/commonHelper.ts rename to Source/configure/helper/commonHelper.ts diff --git a/src/configure/helper/controlProvider.ts b/Source/configure/helper/controlProvider.ts similarity index 100% rename from src/configure/helper/controlProvider.ts rename to Source/configure/helper/controlProvider.ts diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/Source/configure/helper/devOps/azureDevOpsHelper.ts similarity index 100% rename from src/configure/helper/devOps/azureDevOpsHelper.ts rename to Source/configure/helper/devOps/azureDevOpsHelper.ts diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/Source/configure/helper/devOps/serviceConnectionHelper.ts similarity index 100% rename from src/configure/helper/devOps/serviceConnectionHelper.ts rename to Source/configure/helper/devOps/serviceConnectionHelper.ts diff --git a/src/configure/helper/gitHubHelper.ts b/Source/configure/helper/gitHubHelper.ts similarity index 100% rename from src/configure/helper/gitHubHelper.ts rename to Source/configure/helper/gitHubHelper.ts diff --git a/src/configure/helper/graphHelper.ts b/Source/configure/helper/graphHelper.ts similarity index 100% rename from src/configure/helper/graphHelper.ts rename to Source/configure/helper/graphHelper.ts diff --git a/src/configure/helper/mustacheHelper.ts b/Source/configure/helper/mustacheHelper.ts similarity index 100% rename from src/configure/helper/mustacheHelper.ts rename to Source/configure/helper/mustacheHelper.ts diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/Source/configure/helper/remoteServiceUrlHelper.ts similarity index 100% rename from src/configure/helper/remoteServiceUrlHelper.ts rename to Source/configure/helper/remoteServiceUrlHelper.ts diff --git a/src/configure/helper/repoAnalysisHelper.ts b/Source/configure/helper/repoAnalysisHelper.ts similarity index 100% rename from src/configure/helper/repoAnalysisHelper.ts rename to Source/configure/helper/repoAnalysisHelper.ts diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/Source/configure/helper/sodium/SodiumLibHelper.ts similarity index 100% rename from src/configure/helper/sodium/SodiumLibHelper.ts rename to Source/configure/helper/sodium/SodiumLibHelper.ts diff --git a/src/configure/helper/sodium/sodium.d.ts b/Source/configure/helper/sodium/sodium.d.ts similarity index 100% rename from src/configure/helper/sodium/sodium.d.ts rename to Source/configure/helper/sodium/sodium.d.ts diff --git a/src/configure/helper/telemetryHelper.ts b/Source/configure/helper/telemetryHelper.ts similarity index 100% rename from src/configure/helper/telemetryHelper.ts rename to Source/configure/helper/telemetryHelper.ts diff --git a/src/configure/helper/templateHelper.ts b/Source/configure/helper/templateHelper.ts similarity index 100% rename from src/configure/helper/templateHelper.ts rename to Source/configure/helper/templateHelper.ts diff --git a/src/configure/helper/templateParameterHelper.ts b/Source/configure/helper/templateParameterHelper.ts similarity index 100% rename from src/configure/helper/templateParameterHelper.ts rename to Source/configure/helper/templateParameterHelper.ts diff --git a/src/configure/model/Contracts.ts b/Source/configure/model/Contracts.ts similarity index 100% rename from src/configure/model/Contracts.ts rename to Source/configure/model/Contracts.ts diff --git a/src/configure/model/azureDevOps.ts b/Source/configure/model/azureDevOps.ts similarity index 100% rename from src/configure/model/azureDevOps.ts rename to Source/configure/model/azureDevOps.ts diff --git a/src/configure/model/models.ts b/Source/configure/model/models.ts similarity index 100% rename from src/configure/model/models.ts rename to Source/configure/model/models.ts diff --git a/src/configure/model/provisioningConfiguration.ts b/Source/configure/model/provisioningConfiguration.ts similarity index 100% rename from src/configure/model/provisioningConfiguration.ts rename to Source/configure/model/provisioningConfiguration.ts diff --git a/src/configure/model/templateModels.ts b/Source/configure/model/templateModels.ts similarity index 100% rename from src/configure/model/templateModels.ts rename to Source/configure/model/templateModels.ts diff --git a/src/configure/resources/constants.ts b/Source/configure/resources/constants.ts similarity index 100% rename from src/configure/resources/constants.ts rename to Source/configure/resources/constants.ts diff --git a/src/configure/resources/messages.ts b/Source/configure/resources/messages.ts similarity index 100% rename from src/configure/resources/messages.ts rename to Source/configure/resources/messages.ts diff --git a/src/configure/resources/telemetryKeys.ts b/Source/configure/resources/telemetryKeys.ts similarity index 100% rename from src/configure/resources/telemetryKeys.ts rename to Source/configure/resources/telemetryKeys.ts diff --git a/src/configure/resources/tracePoints.ts b/Source/configure/resources/tracePoints.ts similarity index 100% rename from src/configure/resources/tracePoints.ts rename to Source/configure/resources/tracePoints.ts diff --git a/src/configure/templateInputHelper/InputControl.ts b/Source/configure/templateInputHelper/InputControl.ts similarity index 100% rename from src/configure/templateInputHelper/InputControl.ts rename to Source/configure/templateInputHelper/InputControl.ts diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/Source/configure/templateInputHelper/InputControlProvider.ts similarity index 100% rename from src/configure/templateInputHelper/InputControlProvider.ts rename to Source/configure/templateInputHelper/InputControlProvider.ts diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts similarity index 100% rename from src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts rename to Source/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/Source/configure/templateInputHelper/utilities/DataSourceExpression.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceExpression.ts rename to Source/configure/templateInputHelper/utilities/DataSourceExpression.ts diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/Source/configure/templateInputHelper/utilities/DataSourceUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/DataSourceUtility.ts rename to Source/configure/templateInputHelper/utilities/DataSourceUtility.ts diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/Source/configure/templateInputHelper/utilities/InputControlUtility.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/InputControlUtility.ts rename to Source/configure/templateInputHelper/utilities/InputControlUtility.ts diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/Source/configure/templateInputHelper/utilities/VisibilityHelper.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/VisibilityHelper.ts rename to Source/configure/templateInputHelper/utilities/VisibilityHelper.ts diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts similarity index 100% rename from src/configure/templateInputHelper/utilities/validation/StaticValidator.ts rename to Source/configure/templateInputHelper/utilities/validation/StaticValidator.ts diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/Source/configure/templates/azurePipelineTemplates/nodejs.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejs.yml rename to Source/configure/templates/azurePipelineTemplates/nodejs.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/Source/configure/templates/azurePipelineTemplates/pythonDjango.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonDjango.yml rename to Source/configure/templates/azurePipelineTemplates/pythonDjango.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/azurePipelineTemplates/simpleWebApp.yml rename to Source/configure/templates/azurePipelineTemplates/simpleWebApp.yml diff --git a/src/configure/templates/dependencies/deployment.yml b/Source/configure/templates/dependencies/deployment.yml similarity index 100% rename from src/configure/templates/dependencies/deployment.yml rename to Source/configure/templates/dependencies/deployment.yml diff --git a/src/configure/templates/dependencies/ingress.yml b/Source/configure/templates/dependencies/ingress.yml similarity index 100% rename from src/configure/templates/dependencies/ingress.yml rename to Source/configure/templates/dependencies/ingress.yml diff --git a/src/configure/templates/dependencies/service-ingress.yml b/Source/configure/templates/dependencies/service-ingress.yml similarity index 100% rename from src/configure/templates/dependencies/service-ingress.yml rename to Source/configure/templates/dependencies/service-ingress.yml diff --git a/src/configure/templates/dependencies/service.yml b/Source/configure/templates/dependencies/service.yml similarity index 100% rename from src/configure/templates/dependencies/service.yml rename to Source/configure/templates/dependencies/service.yml diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml rename to Source/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml similarity index 100% rename from src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml rename to Source/configure/templates/githubWorkflowTemplates/simpleWebApp.yml diff --git a/src/configure/utilities/templateConverter.ts b/Source/configure/utilities/templateConverter.ts similarity index 100% rename from src/configure/utilities/templateConverter.ts rename to Source/configure/utilities/templateConverter.ts diff --git a/src/configure/utilities/utilities.ts b/Source/configure/utilities/utilities.ts similarity index 100% rename from src/configure/utilities/utilities.ts rename to Source/configure/utilities/utilities.ts diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/Source/configure/utilities/webAppNodeVersionConverter.ts similarity index 100% rename from src/configure/utilities/webAppNodeVersionConverter.ts rename to Source/configure/utilities/webAppNodeVersionConverter.ts diff --git a/src/extension.ts b/Source/extension.ts similarity index 100% rename from src/extension.ts rename to Source/extension.ts diff --git a/src/logger.ts b/Source/logger.ts similarity index 100% rename from src/logger.ts rename to Source/logger.ts diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file From f52439c3ed55acf5cb301ecc639f052696c716d2 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Tue, 10 Sep 2024 23:44:11 +0300 Subject: [PATCH 94/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 131 files changed, 116 insertions(+), 21692 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 6176f58fb57f689d8a7d93e7c49e0226a63b1ec4 Mon Sep 17 00:00:00 2001 From: Nikola Hristov Date: Wed, 11 Sep 2024 00:55:08 +0300 Subject: [PATCH 95/96] --- .azure-pipelines/azure-pipelines.yml | 37 - .azure-pipelines/ci-scan.yml | 27 - .azure-pipelines/common-steps.yml | 56 - .../github-release/github-release.js | 91 - .../github-release/package-lock.json | 279 - .azure-pipelines/github-release/package.json | 14 - .azure-pipelines/release-pipeline.yml | 45 - .github/CODEOWNERS | 1 - .github/workflows/defaultLabel.yml | 21 - .github/workflows/stale.yml | 20 - .vscode/extensions.json | 7 - .vscode/launch.json | 63 - .vscode/settings.json | 18 - .vscode/tasks.json | 20 - package-lock.json | 7999 ----------------- package.json | 283 +- src/configure/activate.ts | 43 - src/configure/browse.ts | 100 - .../clients/IProvisioningServiceClient.ts | 6 - .../clients/ITemplateServiceClient.ts | 12 - .../clients/ProvisioningServiceClient.ts | 52 - .../clients/TemplateServiceClientFactory.ts | 43 - .../clients/azure/appServiceClient.ts | 178 - src/configure/clients/azure/armRestClient.ts | 65 - .../clients/azure/azureResourceClient.ts | 132 - .../clients/devOps/azureDevOpsClient.ts | 371 - .../clients/devOps/serviceConnectionClient.ts | 241 - .../clients/github/TemplateServiceClient.ts | 112 - src/configure/clients/github/githubClient.ts | 156 - .../clients/modaRepositoryAnalysisClient.ts | 27 - ...portalExtensionRepositoryAnalysisClient.ts | 27 - .../provisioningServiceClientFactory.ts | 39 - .../clients/repositoryAnalyisClient.ts | 5 - src/configure/clients/restClient.ts | 52 - src/configure/configure.ts | 766 -- .../configurers/AksAzureResourceSelector.ts | 12 - .../configurers/IAzureResourceSelector.ts | 6 - .../configurers/IProvisioningConfigurer.ts | 10 - .../configurers/ResourceSelectorFactory.ts | 34 - .../WebAppAzureResourceSelector.ts | 31 - .../configurers/azurePipelineConfigurer.ts | 390 - src/configure/configurers/configurerBase.ts | 22 - .../configurers/configurerFactory.ts | 24 - .../localGithubWorkflowConfigurer.ts | 314 - .../configurers/provisioningConfigurer.ts | 304 - .../remoteGitHubWorkflowConfigurer.ts | 247 - src/configure/helper/AssetHandler.ts | 169 - src/configure/helper/DataSourceHandler.ts | 29 - src/configure/helper/LocalGitRepoHelper.ts | 210 - src/configure/helper/azureSessionHelper.ts | 35 - src/configure/helper/commonHelper.ts | 110 - src/configure/helper/controlProvider.ts | 46 - .../helper/devOps/azureDevOpsHelper.ts | 171 - .../helper/devOps/serviceConnectionHelper.ts | 123 - src/configure/helper/gitHubHelper.ts | 43 - src/configure/helper/graphHelper.ts | 229 - src/configure/helper/mustacheHelper.ts | 288 - .../helper/remoteServiceUrlHelper.ts | 88 - src/configure/helper/repoAnalysisHelper.ts | 122 - .../helper/sodium/SodiumLibHelper.ts | 44 - src/configure/helper/sodium/sodium.d.ts | 3 - src/configure/helper/telemetryHelper.ts | 88 - src/configure/helper/templateHelper.ts | 1509 ---- .../helper/templateParameterHelper.ts | 278 - src/configure/model/Contracts.ts | 294 - src/configure/model/azureDevOps.ts | 62 - src/configure/model/models.ts | 298 - .../model/provisioningConfiguration.ts | 53 - src/configure/model/templateModels.ts | 102 - src/configure/resources/constants.ts | 203 - src/configure/resources/messages.ts | 126 - src/configure/resources/telemetryKeys.ts | 55 - src/configure/resources/tracePoints.ts | 47 - .../templateInputHelper/InputControl.ts | 294 - .../InputControlProvider.ts | 268 - .../RepoAnalysisSettingInputProvider.ts | 109 - .../utilities/DataSourceExpression.ts | 174 - .../utilities/DataSourceUtility.ts | 87 - .../utilities/InputControlUtility.ts | 81 - .../utilities/VisibilityHelper.ts | 153 - .../utilities/validation/StaticValidator.ts | 45 - .../dotnetcoreLinuxFunctionApp.yml | 78 - .../dotnetcoreLinuxWebApp.yml | 108 - .../dotnetcoreWindowsFunctionApp.yml | 76 - .../dotnetcoreWindowsWebApp.yml | 105 - .../azurePipelineTemplates/nodejs.yml | 72 - .../nodejsLinuxFunctionApp.yml | 86 - .../nodejsLinuxWebApp.yml | 73 - .../nodejsWindowsFunctionApp.yml | 83 - .../nodejsWithAngular.yml | 73 - .../nodejsWithAngularLinuxWebApp.yml | 74 - .../nodejsWithGrunt.yml | 72 - .../nodejsWithGruntLinuxWebApp.yml | 73 - .../azurePipelineTemplates/nodejsWithGulp.yml | 72 - .../nodejsWithGulpLinuxWebApp.yml | 73 - .../nodejsWithWebpack.yml | 73 - .../nodejsWithWebpackLinuxWebApp.yml | 74 - .../azurePipelineTemplates/pythonDjango.yml | 58 - .../pythonLinuxFunctionApp.yml | 93 - .../pythonLinuxWebApp.yml | 87 - .../simpleLinuxWebApp.yml | 61 - .../azurePipelineTemplates/simpleWebApp.yml | 60 - .../templates/dependencies/deployment.yml | 19 - .../templates/dependencies/ingress.yml | 17 - .../dependencies/service-ingress.yml | 15 - .../templates/dependencies/service.yml | 15 - .../AksWithReuseACR.yml | 62 - .../nodejsLinuxFunctionApp.yml | 45 - .../githubWorkflowTemplates/nodejsOnLinux.yml | 42 - .../nodejsOnWindows.yml | 32 - .../nodejsWindowsFunctionApp.yml | 45 - .../nodejsWithAngularOnLinuxWebApp.yml | 50 - .../nodejsWithAngularOnWindowsWebApp.yml | 36 - .../nodejsWithGruntOnLinuxWebApp.yml | 49 - .../nodejsWithGruntOnWindowsWebApp.yml | 35 - .../nodejsWithGulpOnLinuxWebApp.yml | 49 - .../nodejsWithGulpOnWindowsWebApp.yml | 35 - .../nodejsWithWebpackOnLinuxWebApp.yml | 50 - .../nodejsWithWebpackOnWindowsWebApp.yml | 36 - .../pythonLinuxFunctionApp.yml | 74 - .../pythonLinuxWebApp.yml | 77 - .../githubWorkflowTemplates/simpleWebApp.yml | 20 - src/configure/test/index.ts | 38 - src/configure/test/runTest.ts | 23 - src/configure/test/suite/GitHubClient.test.ts | 122 - src/configure/test/suite/commonHelper.test.ts | 80 - src/configure/utilities/templateConverter.ts | 108 - src/configure/utilities/utilities.ts | 21 - .../utilities/webAppNodeVersionConverter.ts | 38 - src/extension.ts | 93 - src/logger.ts | 20 - 131 files changed, 116 insertions(+), 21692 deletions(-) delete mode 100644 .azure-pipelines/azure-pipelines.yml delete mode 100644 .azure-pipelines/ci-scan.yml delete mode 100644 .azure-pipelines/common-steps.yml delete mode 100644 .azure-pipelines/github-release/github-release.js delete mode 100644 .azure-pipelines/github-release/package-lock.json delete mode 100644 .azure-pipelines/github-release/package.json delete mode 100644 .azure-pipelines/release-pipeline.yml delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/workflows/defaultLabel.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 package-lock.json delete mode 100644 src/configure/activate.ts delete mode 100644 src/configure/browse.ts delete mode 100644 src/configure/clients/IProvisioningServiceClient.ts delete mode 100644 src/configure/clients/ITemplateServiceClient.ts delete mode 100644 src/configure/clients/ProvisioningServiceClient.ts delete mode 100644 src/configure/clients/TemplateServiceClientFactory.ts delete mode 100644 src/configure/clients/azure/appServiceClient.ts delete mode 100644 src/configure/clients/azure/armRestClient.ts delete mode 100644 src/configure/clients/azure/azureResourceClient.ts delete mode 100644 src/configure/clients/devOps/azureDevOpsClient.ts delete mode 100644 src/configure/clients/devOps/serviceConnectionClient.ts delete mode 100644 src/configure/clients/github/TemplateServiceClient.ts delete mode 100644 src/configure/clients/github/githubClient.ts delete mode 100644 src/configure/clients/modaRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/portalExtensionRepositoryAnalysisClient.ts delete mode 100644 src/configure/clients/provisioningServiceClientFactory.ts delete mode 100644 src/configure/clients/repositoryAnalyisClient.ts delete mode 100644 src/configure/clients/restClient.ts delete mode 100644 src/configure/configure.ts delete mode 100644 src/configure/configurers/AksAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IAzureResourceSelector.ts delete mode 100644 src/configure/configurers/IProvisioningConfigurer.ts delete mode 100644 src/configure/configurers/ResourceSelectorFactory.ts delete mode 100644 src/configure/configurers/WebAppAzureResourceSelector.ts delete mode 100644 src/configure/configurers/azurePipelineConfigurer.ts delete mode 100644 src/configure/configurers/configurerBase.ts delete mode 100644 src/configure/configurers/configurerFactory.ts delete mode 100644 src/configure/configurers/localGithubWorkflowConfigurer.ts delete mode 100644 src/configure/configurers/provisioningConfigurer.ts delete mode 100644 src/configure/configurers/remoteGitHubWorkflowConfigurer.ts delete mode 100644 src/configure/helper/AssetHandler.ts delete mode 100644 src/configure/helper/DataSourceHandler.ts delete mode 100644 src/configure/helper/LocalGitRepoHelper.ts delete mode 100644 src/configure/helper/azureSessionHelper.ts delete mode 100644 src/configure/helper/commonHelper.ts delete mode 100644 src/configure/helper/controlProvider.ts delete mode 100644 src/configure/helper/devOps/azureDevOpsHelper.ts delete mode 100644 src/configure/helper/devOps/serviceConnectionHelper.ts delete mode 100644 src/configure/helper/gitHubHelper.ts delete mode 100644 src/configure/helper/graphHelper.ts delete mode 100644 src/configure/helper/mustacheHelper.ts delete mode 100644 src/configure/helper/remoteServiceUrlHelper.ts delete mode 100644 src/configure/helper/repoAnalysisHelper.ts delete mode 100644 src/configure/helper/sodium/SodiumLibHelper.ts delete mode 100644 src/configure/helper/sodium/sodium.d.ts delete mode 100644 src/configure/helper/telemetryHelper.ts delete mode 100644 src/configure/helper/templateHelper.ts delete mode 100644 src/configure/helper/templateParameterHelper.ts delete mode 100644 src/configure/model/Contracts.ts delete mode 100644 src/configure/model/azureDevOps.ts delete mode 100644 src/configure/model/models.ts delete mode 100644 src/configure/model/provisioningConfiguration.ts delete mode 100644 src/configure/model/templateModels.ts delete mode 100644 src/configure/resources/constants.ts delete mode 100644 src/configure/resources/messages.ts delete mode 100644 src/configure/resources/telemetryKeys.ts delete mode 100644 src/configure/resources/tracePoints.ts delete mode 100644 src/configure/templateInputHelper/InputControl.ts delete mode 100644 src/configure/templateInputHelper/InputControlProvider.ts delete mode 100644 src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceExpression.ts delete mode 100644 src/configure/templateInputHelper/utilities/DataSourceUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/InputControlUtility.ts delete mode 100644 src/configure/templateInputHelper/utilities/VisibilityHelper.ts delete mode 100644 src/configure/templateInputHelper/utilities/validation/StaticValidator.ts delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejs.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonDjango.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml delete mode 100644 src/configure/templates/azurePipelineTemplates/simpleWebApp.yml delete mode 100644 src/configure/templates/dependencies/deployment.yml delete mode 100644 src/configure/templates/dependencies/ingress.yml delete mode 100644 src/configure/templates/dependencies/service-ingress.yml delete mode 100644 src/configure/templates/dependencies/service.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml delete mode 100644 src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml delete mode 100644 src/configure/test/index.ts delete mode 100644 src/configure/test/runTest.ts delete mode 100644 src/configure/test/suite/GitHubClient.test.ts delete mode 100644 src/configure/test/suite/commonHelper.test.ts delete mode 100644 src/configure/utilities/templateConverter.ts delete mode 100644 src/configure/utilities/utilities.ts delete mode 100644 src/configure/utilities/webAppNodeVersionConverter.ts delete mode 100644 src/extension.ts delete mode 100644 src/logger.ts diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml deleted file mode 100644 index 32bf579f..00000000 --- a/.azure-pipelines/azure-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# CI and PR build script -# -# There should be no deep magic here. The developer experience and CI experience -# must remain as close to one another as possible. -# -# Developer experience: -# npm install -# (make changes) -# npm test -# vsce package -# (give VSIX to someone for buddy testing) -trigger: -- master - -# no `pr` keyword because we want all PRs to run this - -pool: - vmImage: ubuntu-latest - -steps: -# for convenience, we tag CI-produced packages with a version number -# pointing to the commit which was built. for PRs, also include the PR #. -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - - if [ -n "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; then - VERSION_STRING=${PACKAGE_VERSION}-pr-${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}-$(git rev-parse --short HEAD) - else - VERSION_STRING=${PACKAGE_VERSION}-ci-$(git rev-parse --short HEAD) - fi - - npm --no-git-tag-version version $VERSION_STRING - echo "##vso[build.updatebuildnumber]${VERSION_STRING}_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of package and build - -- template: common-steps.yml diff --git a/.azure-pipelines/ci-scan.yml b/.azure-pipelines/ci-scan.yml deleted file mode 100644 index e229283d..00000000 --- a/.azure-pipelines/ci-scan.yml +++ /dev/null @@ -1,27 +0,0 @@ -pool: - vmImage: vs2017-win2016 - -steps: -- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2 - displayName: 'Run CredScan' - inputs: - toolMajorVersion: V2 - debugMode: false - suppressionsFile: .config/CredScanSuppressions.json - -- task: TSLint@1 - inputs: - RuleLibrary: 'microsoft' - RulesetMicrosoft: 'mssdlrequired' - FileSelectionType: 'fileGlob' - Files: '**\*.ts' - ECMAScriptVersion: 'ES6' - OutputFormat: 'json' - TypeScriptVersion: 'custom' - TypeScriptVersionCustom: '3.3.1' - -- task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1 - displayName: 'Post Analysis' - inputs: - CredScan: true - TSLint: true diff --git a/.azure-pipelines/common-steps.yml b/.azure-pipelines/common-steps.yml deleted file mode 100644 index 690ad10e..00000000 --- a/.azure-pipelines/common-steps.yml +++ /dev/null @@ -1,56 +0,0 @@ -# Common steps template -# -# Things which happen regardless of CI, PR, or release builds -steps: - - script: npm install - displayName: npm install - - - script: npm run compile - displayName: Build extension - - # TODO: call the schema endpoint to generate the shipped schema file - # - script: | - # echo no-op - # displayName: Generate service-schema.json - - # - script: npm run unittest - # displayName: Run unit tests - - # Acquire the `vsce` tool and use it to package - - script: | - sudo npm install -g vsce - vsce package - displayName: Create VSIX - - - script: | - npm run vscode:prepublish - cat /home/vsts/.npm/_logs/*.log - displayName: Echo npm error logs on failure - condition: failed() - - # For releasable builds, we'll want the branch and the changelog - # Expects that a 'version.txt' has been laid down by a previous step - - bash: | - echo $(Build.SourceBranch) | sed "s|refs/[^/]*/||" > branch.txt - PACKAGE_VERSION=$(cat version.txt) - VERSION_REGEX="## $(echo $PACKAGE_VERSION | sed 's/\./\\./g')" - sed -n "/$VERSION_REGEX/,/## 1\..*/p" CHANGELOG.md | head -n -2 > minichangelog.txt - displayName: Get branch and mini-changelog - - # Choose files to publish - - task: CopyFiles@2 - displayName: Stage VSIX for publishing - inputs: - contents: |- - *.vsix - version.txt - branch.txt - minichangelog.txt - targetFolder: $(Build.ArtifactStagingDirectory) - - # Publish files as an artifact - - task: PublishPipelineArtifact@1 - displayName: Publish VSIX - inputs: - artifact: vscode-deploy-azure - targetPath: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/github-release/github-release.js b/.azure-pipelines/github-release/github-release.js deleted file mode 100644 index eaaf0478..00000000 --- a/.azure-pipelines/github-release/github-release.js +++ /dev/null @@ -1,91 +0,0 @@ -const octokit = require('@octokit/rest')({ - headers: { - 'user-agent': 'azure-pipelines/vscode-release-pipeline v1.0' - } -}); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const fs = require('fs'); - -const DEBUG_LOGGING = process.env.SYSTEM_DEBUG && process.env.SYSTEM_DEBUG == 'true'; -let vsixName = process.argv[2] || null; -let version = process.argv[3] || null; -let token = process.argv[4] || null -if (token === null) { - console.log(`Usage: - - github-release.js - -This will create a new release and tag on GitHub at the current HEAD commit. - -USE AT YOUR OWN RISK. -This is intended to be run by the release pipeline only.`); - process.exit(1); -} - -async function createRelease() { - let target_commitish; - if (process.env.BUILD_SOURCEBRANCH) { - target_commitish = process.env.BUILD_SOURCEBRANCH; - } else { - const { stdout: head_commit } = await exec('git rev-parse --verify HEAD'); - target_commitish = head_commit.trim(); - } - - const { stdout: body } = await exec('cat minichangelog.txt'); - - octokit.authenticate({ - type: 'token', - token: token - }); - - console.log('Creating release...'); - let createReleaseResult; - try { - createReleaseResult = await octokit.repos.createRelease({ - owner: 'Microsoft', - repo: 'vscode-deploy-azure', - tag_name: `v${version}`, - target_commitish: target_commitish, - name: `${version}`, - body: body - }); - } catch (e) { - throw e; - } - console.log('Created release.'); - - if (DEBUG_LOGGING) { - console.log(createReleaseResult); - } - - const vsixSize = fs.statSync(vsixName).size; - - console.log('Uploading VSIX...'); - let uploadResult; - try { - uploadResult = await octokit.repos.uploadAsset({ - url: createReleaseResult.data.upload_url, - headers: { - 'content-length': vsixSize, - 'content-type': 'application/zip', - }, - name: vsixName, - file: fs.createReadStream(vsixName) - }); - } catch (e) { - throw e; - } - console.log('Uploaded VSIX.'); - - if (DEBUG_LOGGING) { - console.log(uploadResult); - } -} - -try { - createRelease(); -} catch (err) { - console.error(err); - process.exit(1); -} diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json deleted file mode 100644 index cce73f04..00000000 --- a/.azure-pipelines/github-release/package-lock.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "15.18.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.2.tgz", - "integrity": "sha512-cXP/hzh21PoZe0HJ74Co33HS3ITayWujXXeb1P8oR9kXt3hEmGsm2FQ4A8PrqV18C26uYkIb4KjjlVBzX1aHjw==", - "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "before-after-hook": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", - "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" - }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "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" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "universal-user-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", - "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", - "requires": { - "os-name": "^3.0.0" - } - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", - "requires": { - "execa": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/.azure-pipelines/github-release/package.json b/.azure-pipelines/github-release/package.json deleted file mode 100644 index 2ef60327..00000000 --- a/.azure-pipelines/github-release/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "github-release", - "version": "1.0.0", - "description": "", - "main": "github-release.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Microsoft", - "license": "MIT", - "dependencies": { - "@octokit/rest": "^15.18.2" - } -} diff --git a/.azure-pipelines/release-pipeline.yml b/.azure-pipelines/release-pipeline.yml deleted file mode 100644 index d95c2db6..00000000 --- a/.azure-pipelines/release-pipeline.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Release build script -# -# Uses the common build logic, but also gains capabilities related to releasing the product. - -# Only trigger manually -trigger: none -pr: none - -pool: - vmImage: ubuntu-16.04 - -steps: -# release version should be correctly set in package.json -- bash: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "##vso[build.updatebuildnumber]${PACKAGE_VERSION}_release_${BUILD_BUILDID}" - echo "$PACKAGE_VERSION" > version.txt - displayName: Set version number of build - -# do all the normal build stuff -- template: common-steps.yml - -# if the mini changelog is empty, complain -- bash: | - LINE_COUNT=$(cat minichangelog.txt | wc -l) - if [ "$LINE_COUNT" -lt 3 ]; then - echo Mini changelog is too short. Did you use the wrong version number in CHANGELOG.txt? - exit 1 - fi - displayName: Check for length of mini-changelog - -# create a GitHub Release -- bash: | - export npm_config_cache=$(Build.SourcesDirectory)/.azure-pipelines/github-release/npm-cache - npm install - displayName: Prepare to create GitHub Release - workingDirectory: '$(Build.SourcesDirectory)/.azure-pipelines/github-release' -- bash: | - SCRIPT=.azure-pipelines/github-release/github-release.js - VSIX=*.vsix - VERSION=$(node -p "require('./package.json').version") - node $SCRIPT $VSIX $VERSION $GITHUB_TOKEN - displayName: Create GitHub Release - env: - GITHUB_TOKEN: $(GitHubSecret) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 23a746b6..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @bishal-pdmsft @vineetmimrot @kanika1894 @anuragc617 diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml deleted file mode 100644 index 8466ee9b..00000000 --- a/.github/workflows/defaultLabel.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Mark issues "default" - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is marked default for generating issues report.' - stale-issue-label: 'default' - days-before-stale: 0 - days-before-close: -1 - operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e0bc5b99..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: "0 0/3 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." - stale-issue-label: "stale" - days-before-stale: 7 - days-before-close: -1 - operations-per-run: 100 - exempt-issue-labels: "backlog" diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ee71911b..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "eg2.tslint" - ] -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 1dadb93d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,63 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "env": { - // Uncomment below line to show telemetry on Debug console - // "DEBUGTELEMETRY": "v", - } - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/src/test/workspace/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" - ] - }, - { - "name": "Extension Tests From Server", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceRoot}/examples/", - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/testfromserver" - ], - "outFiles": [ - "${workspaceFolder}/out/testfromserver/**/*.js" - ] - }, - { - "name": "Attach to Server", - "type": "node", - "request": "attach", - "port": 6009, - "restart": true, - "outFiles": [ - "${workspaceRoot}/node_modules/azure-pipelines-language-server/**/*.js" - ] - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 7856ef0b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", - "typescript.tsdk": "node_modules/typescript/lib", - "editor.codeActionsOnSave": { - "source.organizeImports": true // Sort and remove unused imports - }, - // Turn it on if you want to see errors from all the files - "typescript.tsserver.experimental.enableProjectDiagnostics": false, - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 604e38f5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2aa9297a..00000000 --- a/package-lock.json +++ /dev/null @@ -1,7999 +0,0 @@ -{ - "name": "azure-deploy", - "version": "1.2.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/mustache": { - "version": "0.8.32", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-0.8.32.tgz", - "integrity": "sha512-RTVWV485OOf4+nO2+feurk0chzHkSjkjALiejpHltyuMf/13fGymbbNNFrSKdSSUg1TIwzszXdWsVirxgqYiFA==", - "dev": true - }, - "@types/node": { - "version": "7.0.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", - "integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==", - "dev": true - }, - "@types/q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", - "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz", - "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.1.tgz", - "integrity": "sha512-rdBIeMQyRBOXogop/EYBvSkYFn9D9yGxUa5hagBVG55KIdSUbp22EACJSHCs6kmmfunojAhf7zJH+Ds06/qLaQ==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.13", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.13.tgz", - "integrity": "sha512-RYmIHOWSxnTTa765N6jJBVE45pd2SYNblEYshVDduLw6RhocazNmRzE5/ytvBD8IkDMH6DI+bcrqxh8NILimBA==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "@types/webpack-sources": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", - "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - } - }, - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "adal-node": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.1.28.tgz", - "integrity": "sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=", - "requires": { - "@types/node": "^8.0.47", - "async": ">=0.6.0", - "date-utils": "*", - "jws": "3.x.x", - "request": ">= 2.52.0", - "underscore": ">= 1.3.1", - "uuid": "^3.1.0", - "xmldom": ">= 0.1.x", - "xpath.js": "~1.1.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", - "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==" - } - } - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "applicationinsights": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.4.0.tgz", - "integrity": "sha512-TV8MYb0Kw9uE2cdu4V/UvTKdOABkX2+Fga9iDz0zqV7FLrNXfmAugWZmmdTx4JoynYkln3d5CUHY3oVSUEbfFw==", - "requires": { - "cls-hooked": "^4.2.2", - "continuation-local-storage": "^3.2.1", - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "^0.3.2" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "archiver": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", - "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^2.6.3", - "buffer-crc32": "^0.2.1", - "glob": "^7.1.4", - "readable-stream": "^3.4.0", - "tar-stream": "^2.1.0", - "zip-stream": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "azure-arm-resource": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-7.3.0.tgz", - "integrity": "sha512-2K+ps1Iwa4PBQFwdCn1X8kAVIRLH5M7nlNZtfOWaYd7DXJ131qJpwW8ul6gKZgG7DAI3PBodrGsHFvPdgA+AzQ==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azure-arm-storage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/azure-arm-storage/-/azure-arm-storage-3.2.0.tgz", - "integrity": "sha512-jrew8qgqCiJ66QyjAhQis7AXhK6hp5soypvcxio3g/b1mNJr7RsQ6vD5zBRebcvM+QBGzvv7COiXy/xzibyOgA==", - "requires": { - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.3.3" - } - }, - "azure-arm-website": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/azure-arm-website/-/azure-arm-website-5.7.0.tgz", - "integrity": "sha512-GnwqaelTIhv40YI3Ch8+Q272X6XXWTq99Y1aYWZb1cejSP4gjrWWeppwor4HtjlVU9i9YIvYO91TRjQt8FrHVA==", - "requires": { - "ms-rest": "^2.3.3", - "ms-rest-azure": "^2.5.5" - } - }, - "azureintegration-repoanalysis-client-internal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/azureintegration-repoanalysis-client-internal/-/azureintegration-repoanalysis-client-internal-1.0.0.tgz", - "integrity": "sha512-k/VvC8DWQB0tQeWlgDgOX5IVKqoTjfsGb75Cv03b5nr099gqm14cd3KdSwI4Ox0YzlOobxGRn6FNUOkO3Jd6jg==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compress-commons": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", - "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^3.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cpx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", - "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", - "dev": true, - "requires": { - "babel-runtime": "^6.9.2", - "chokidar": "^1.6.0", - "duplexer": "^0.1.1", - "glob": "^7.0.5", - "glob2base": "^0.0.12", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "resolve": "^1.1.7", - "safe-buffer": "^5.0.1", - "shell-quote": "^1.6.1", - "subarg": "^1.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", - "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-utils": { - "version": "1.2.21", - "resolved": "https://registry.npmjs.org/date-utils/-/date-utils-1.2.21.tgz", - "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "requires": { - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "diagnostic-channel-publishers": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.3.tgz", - "integrity": "sha512-qIocRYU5TrGUkBlDDxaziAK1+squ8Yf2Ls4HldL3xxb/jzmWO2Enux7CvevNKYmF2kDXZ9HiRqwjPsjk8L+i2Q==" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filemanager-webpack-plugin": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-2.0.5.tgz", - "integrity": "sha512-Yj5XIdKI2AN2r66uZc4MZ/n18SMqe2KKlkAqHHMW1OwveDs2Vc5129CpbFcI73rq/rjqso+2HsxieS7u5sx6XA==", - "dev": true, - "requires": { - "archiver": "^3.0.0", - "cpx": "^1.5.0", - "fs-extra": "^7.0.0", - "make-dir": "^1.1.0", - "mv": "^2.1.1", - "rimraf": "^2.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" - } - }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-4.0.0.tgz", - "integrity": "sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==", - "requires": { - "he": "^1.0.0", - "htmlparser2": "^3.9.2", - "lodash": "^4.17.4", - "optimist": "^0.6.1" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpath-plus": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-3.0.0.tgz", - "integrity": "sha512-WQwgWEBgn+SJU1tlDa/GiY5/ngRpa9yrSj8n4BYPHcwoxTDaMEaYCHMOn42hIHHDd3CrUoRr3+HpsK0hCKoxzA==" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, - "requires": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "ms-rest": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/ms-rest/-/ms-rest-2.5.3.tgz", - "integrity": "sha512-p0CnzrTzEkS8UTEwgCqT2O5YVK9E8KGBBlJVm3hFtMZvf0dmncKYXWFPyUa4PAsfBL7h4jfu39tOIFTu6exntg==", - "requires": { - "duplexer": "^0.1.1", - "is-buffer": "^1.1.6", - "is-stream": "^1.1.0", - "moment": "^2.21.0", - "request": "^2.88.0", - "through": "^2.3.8", - "tunnel": "0.0.5", - "uuid": "^3.2.1" - } - }, - "ms-rest-azure": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz", - "integrity": "sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==", - "requires": { - "adal-node": "^0.1.28", - "async": "2.6.0", - "moment": "^2.22.2", - "ms-rest": "^2.3.2", - "request": "^2.88.0", - "uuid": "^3.2.1" - } - }, - "mustache": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.0.1.tgz", - "integrity": "sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "dev": true, - "requires": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "dev": true, - "requires": { - "glob": "^6.0.1" - } - } - } - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nock": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.2.tgz", - "integrity": "sha512-Wm8H22iT3UKPDf138tmgJ0NRfCLd9f2LByki9T2mGHnB66pEqvJh3gV/up1ZufZF24n7/pDYyLGybdqOzF3JIw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", - "propagate": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.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" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-light": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.5.tgz", - "integrity": "sha512-eBEh+GzJAftUnex6tcL6eV2JCifY0+sZMIUpUPOVXbs2nV5hla4ZMmO3icYKGuGVuQ2zHE9evh4OrRcH4iyYYw==", - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "vscode-nls": "^4.1.1" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", - "requires": { - "debug": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - } - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", - "dev": true, - "requires": { - "bl": "^4.0.1", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "dev": true, - "requires": { - "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", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "ts-loader": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", - "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", - "micromatch": "^3.1.4", - "semver": "^5.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.2.0.tgz", - "integrity": "sha512-6tfi/2tHqV/3CL77pULBcK+foty11Rr0idRDxKnteTaKm6gWF9qmaCNU17HVssOuwlYNyOmd9Jsmjd+1t3a3qw==", - "dev": true, - "requires": { - "tsutils": "^2.27.2 <2.29.0" - }, - "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", - "integrity": "sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - }, - "tweetsodium": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tweetsodium/-/tweetsodium-0.0.4.tgz", - "integrity": "sha512-nTYzcaSmpd2vcfI8DriuO01l+jIF8TmjNxjFPRyJkdzi5IdJbUstT3G1rk8V9YkzrucNSWoSrA9Z5Yp3RW2cgw==", - "requires": { - "blakejs": "^1.1.0", - "tweetnacl": "^1.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typed-rest-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.7.tgz", - "integrity": "sha512-0u+4yiprNuCoXzWllWuDB81i5Riyg0nwrMFs9RczRjU0ZzIWG4lodtXNxoBL19Jb9I8qVN/VTBG7x+mR2kvq+A==", - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - }, - "dependencies": { - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", - "dev": true - }, - "typescript-tslint-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", - "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4", - "mock-require": "^3.0.3", - "vscode-languageserver": "^5.2.1" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", - "dev": true - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "dev": true, - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - } - }, - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "vscode": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.33.tgz", - "integrity": "sha512-sXedp2oF6y4ZvqrrFiZpeMzaCLSWV+PpYkIxjG/iYquNZ9KrLL2LujltGxPLvzn49xu2sZkyC+avVNFgcJD1Iw==", - "dev": true, - "requires": { - "glob": "^7.1.2", - "mocha": "^4.0.1", - "request": "^2.88.0", - "semver": "^5.4.1", - "source-map-support": "^0.5.0", - "url-parse": "^1.4.4", - "vscode-test": "^0.1.4" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "vscode-test": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.1.5.tgz", - "integrity": "sha512-s+lbF1Dtasc0yXVB9iQTexBe2JK6HJAUJe3fWezHKIjq+xRw5ZwCMEMBaonFIPy7s95qg2HPTRDR5W4h4kbxGw==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1" - } - } - } - }, - "vscode-azureextensiondev": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/vscode-azureextensiondev/-/vscode-azureextensiondev-0.3.4.tgz", - "integrity": "sha512-d8ltYPTM8TfYzVtujzOnqeC7/H10WVwadSnR2R+4Xh8tzbmrDsq1b3pUElKqyt50uaXR7bQGPJaIomWL/AfBaw==", - "dev": true, - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "clean-webpack-plugin": "^3.0.0", - "filemanager-webpack-plugin": "^2.0.5", - "fs-extra": "^8.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "terser-webpack-plugin": "^1.2.2", - "ts-loader": "^5.3.3", - "webpack": "4.28.1" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "dev": true, - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "vscode-azureextensionui": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/vscode-azureextensionui/-/vscode-azureextensionui-0.26.3.tgz", - "integrity": "sha512-bWWj7S4+PSAFgwoHUcZSnjo0s7qLNAHxn/yY4EbvyzjPff83BgMe6Mkla+h0F7l33Pfc75VZoZKl3v6kNNzwcA==", - "requires": { - "azure-arm-resource": "^3.0.0-preview", - "azure-arm-storage": "^3.1.0", - "fs-extra": "^4.0.3", - "html-to-text": "^4.0.0", - "ms-rest": "^2.2.2", - "ms-rest-azure": "^2.4.4", - "opn": "^6.0.0", - "semver": "^5.6.0", - "vscode-extension-telemetry": "^0.1.0", - "vscode-nls": "^4.0.0" - }, - "dependencies": { - "azure-arm-resource": { - "version": "3.0.0-preview", - "resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-3.0.0-preview.tgz", - "integrity": "sha512-5AxK9Nnk9hRDtyiXkaqvHV2BvII12JpPpTTHL8p9ZKgkwy67mWk+repoe9PnjxwG2Rm1RadutonccynJ+VHVAw==", - "requires": { - "ms-rest": "^2.0.0", - "ms-rest-azure": "^2.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "vscode-extension-telemetry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.2.tgz", - "integrity": "sha512-FSbaZKlIH3VKvBJsKw7v5bESWHXzltji2rtjaJeJglpQH4tfClzwHMzlMXUZGiblV++djEzb1gW8mb5E+wxFsg==", - "requires": { - "applicationinsights": "1.4.0" - } - }, - "vscode-nls": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz", - "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==" - } - } - }, - "vscode-extension-telemetry": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz", - "integrity": "sha512-Vw3Sr+dZwl+c6PlsUwrTtCOJkgrmvS3OUVDQGcmpXWAgq9xGq6as0K4pUx+aGqTjzLAESmWSrs6HlJm6J6Khcg==", - "requires": { - "applicationinsights": "1.0.1" - }, - "dependencies": { - "applicationinsights": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", - "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", - "requires": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" - } - } - }, - "vscode-json-languageservice": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz", - "integrity": "sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==", - "requires": { - "jsonc-parser": "^2.2.1", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageclient": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", - "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", - "requires": { - "semver": "^5.5.0", - "vscode-languageserver-protocol": "3.14.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz", - "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "vscode-nls": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.4.tgz", - "integrity": "sha512-FTjdqa4jDDoBjJqr36O8lmmZf/55kQ2w4ZY/+GL6K92fq765BqO3aYw21atnXUno/P04V5DWagNl4ybDIndJsw==" - }, - "vscode-test": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", - "integrity": "sha512-Jt7HNGvSE0+++Tvtq5wc4hiXLIr2OjDShz/gbAfM/mahQpy4rKBnmOK33D+MR67ATWviQhl+vpmU3p/qwSH/Pg==", - "dev": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.4", - "rimraf": "^2.6.3" - } - }, - "vscode-uri": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", - "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" - }, - "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", - "dev": true, - "requires": { - "chokidar": "^2.1.8", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.1.tgz", - "integrity": "sha512-qAS7BFyS5iuOZzGJxyDXmEI289h7tVNtJ5XMxf6Tz55J2riOyH42uaEsWF0F32TRaI+54SmI6qRgHM3GzsZ+sQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^5.6.2", - "acorn-dynamic-import": "^3.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yaml-ast-parser-custom-tags": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz", - "integrity": "sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==" - }, - "yaml-language-server": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-0.8.0.tgz", - "integrity": "sha512-+mvpHHPyQo/cNnEdrydH7h13FC393FQ9Uj88W/BbTdAANDy7eTHlmqPDzvv6X5HKl5fi5RLWCWsO4SdAx0WEMw==", - "requires": { - "js-yaml": "^3.13.1", - "jsonc-parser": "^2.2.1", - "prettier": "^1.18.2", - "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.6.0", - "vscode-languageserver": "^5.2.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^4.1.2", - "vscode-uri": "^2.1.1", - "yaml-ast-parser-custom-tags": "0.0.43" - }, - "dependencies": { - "vscode-jsonrpc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", - "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" - }, - "vscode-languageserver": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", - "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", - "requires": { - "vscode-languageserver-protocol": "3.14.1", - "vscode-uri": "^1.0.6" - }, - "dependencies": { - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==" - } - } - }, - "vscode-languageserver-protocol": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", - "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", - "requires": { - "vscode-jsonrpc": "^4.0.0", - "vscode-languageserver-types": "3.14.0" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", - "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" - } - } - }, - "vscode-nls": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", - "integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==" - }, - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "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.2" - }, - "dependencies": { - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zip-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", - "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^2.1.1", - "readable-stream": "^3.4.0" - } - }, - "zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 9d4182a2..64e0e50c 100644 --- a/package.json +++ b/package.json @@ -1,168 +1,117 @@ { - "name": "azure-deploy", - "displayName": "Deploy to Azure", - "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", - "version": "1.2.3", - "publisher": "ms-vscode-deploy-azure", - "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", - "repository": { - "type": "git", - "url": "https://github.com/Microsoft/vscode-deploy-azure" - }, - "homepage": "https://github.com/Microsoft/vscode-deploy-azure/blob/master/README.md", - "bugs": "https://github.com/Microsoft/vscode-deploy-azure/issues/", - "license": "MIT", - "icon": "assets/deployToAzure.png", - "galleryBanner": { - "color": "#D4DCEC", - "theme": "light" - }, - "engines": { - "vscode": "^1.32.0" - }, - "categories": [ - "Programming Languages", - "Formatters", - "Azure" - ], - "tags": [ - "azure-pipelines", - "Azure Pipelines", - "Deploy to Azure", - "YAML" - ], - "keywords": [ - "YAML", - "Azure Pipelines", - "continuous integration", - "CI/CD" - ], - "activationEvents": [ - "*" - ], - "main": "./out/extension", - "contributes": { - "languages": [ - { - "id": "yaml", - "aliases": [ - "YAML", - "yaml" - ], - "extensions": [ - ".yml", - ".eyaml", - ".eyml", - ".yaml" - ] - } - ], - "grammars": [ - { - "language": "yaml", - "scopeName": "source.yaml", - "path": "./syntaxes/yaml.tmLanguage.json" - } - ], - "commands": [ - { - "command": "configure-cicd-pipeline", - "title": "Configure CI/CD Pipeline", - "category": "Deploy to Azure" - }, - { - "command": "browse-cicd-pipeline", - "title": "Browse Pipeline", - "category": "Deploy to Azure" - } - ], - "menus": { - "explorer/context": [ - { - "command": "configure-cicd-pipeline", - "group": "Deploy to Azure", - "when": "explorerResourceIsFolder == true" - } - ], - "commandPalette": [ - { - "command": "browse-cicd-pipeline", - "when": "never" - } - ] - }, - "configuration": { - "title": "Deploy to Azure", - "properties": { - "deployToAzure.UseAzurePipelinesForGithub": { - "type": "boolean", - "default": false, - "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code." - }, - "deployToAzure.UseGithubForCreatingNewRepository": { - "type": "boolean", - "default": true, - "description": "Use GitHub for creating new repository" - } - } - } - }, - "scripts": { - "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./ && node copyStaticFiles.js", - "watch": "node copyStaticFiles.js && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "pretest": "npm run compile", - "test": "node ./out/configure/test/runTest.js" - }, - "devDependencies": { - "@types/fs-extra": "4.0.5", - "@types/glob": "^7.1.1", - "@types/js-yaml": "^3.12.1", - "@types/mocha": "^7.0.2", - "@types/mustache": "0.8.32", - "@types/node": "^7.0.43", - "@types/q": "1.5.0", - "@types/underscore": "1.8.9", - "ajv": "^6.9.1", - "assert": "1.4.1", - "chai": "^4.2.0", - "glob": "^7.1.6", - "mocha": "^7.1.2", - "nock": "^13.0.2", - "ts-node": "7.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "^6.2.0", - "typescript": "3.3.1", - "typescript-tslint-plugin": "^0.5.5", - "vscode": "1.1.37", - "vscode-azureextensiondev": "^0.3.1", - "vscode-test": "^1.3.0" - }, - "dependencies": { - "azure-arm-resource": "7.3.0", - "azure-arm-website": "5.7.0", - "azureintegration-repoanalysis-client-internal": "^1.0.0", - "fs-extra": "^9.0.1", - "js-yaml": "^3.13.1", - "jsonpath-plus": "^3.0.0", - "mustache": "3.0.1", - "q": "1.5.1", - "semver": "^7.3.2", - "shelljs": "^0.3.0", - "simple-git": "^1.110.0", - "tweetsodium": "0.0.4", - "typed-rest-client": "1.0.7", - "underscore": "1.9.1", - "uuid": "^3.3.2", - "vscode-azureextensionui": "0.26.3", - "vscode-extension-telemetry": "0.0.18", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "3.2.4", - "vscode-uri": "1.0.6", - "yaml-language-server": "^0.8.0" - }, - "extensionDependencies": [ - "ms-vscode.azure-account" - ] -} \ No newline at end of file + "activationEvents": [ + "*" + ], + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", + "contributes": { + "commands": [ + { + "category": "Deploy to Azure", + "command": "configure-cicd-pipeline", + "title": "Configure CI/CD Pipeline" + }, + { + "category": "Deploy to Azure", + "command": "browse-cicd-pipeline", + "title": "Browse Pipeline" + } + ], + "configuration": { + "properties": { + "deployToAzure.UseAzurePipelinesForGithub": { + "default": false, + "description": "Setup CI/CD in Azure Pipelines for GitHub Repositories. Please note that this setting is ignored while configuring the CI/CD workflows in Azure Kubernetes Service extension for Visual Studio Code.", + "type": "boolean" + }, + "deployToAzure.UseGithubForCreatingNewRepository": { + "default": true, + "description": "Use GitHub for creating new repository", + "type": "boolean" + } + }, + "title": "Deploy to Azure" + }, + "grammars": [ + { + "language": "yaml", + "path": "./syntaxes/yaml.tmLanguage.json", + "scopeName": "source.yaml" + } + ], + "languages": [ + { + "aliases": [ + "YAML", + "yaml" + ], + "extensions": [ + ".yml", + ".eyaml", + ".eyml", + ".yaml" + ], + "id": "yaml" + } + ], + "menus": { + "commandPalette": [ + { + "command": "browse-cicd-pipeline", + "when": "never" + } + ], + "explorer/context": [ + { + "command": "configure-cicd-pipeline", + "group": "Deploy to Azure", + "when": "explorerResourceIsFolder == true" + } + ] + } + }, + "dependencies": { + "fs-extra": "^9.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^3.0.0", + "mustache": "3.0.1", + "q": "1.5.1", + "semver": "^7.3.2", + "shelljs": "^0.3.0", + "simple-git": "^1.110.0", + "tweetsodium": "0.0.4", + "typed-rest-client": "1.0.7", + "underscore": "1.9.1", + "uuid": "^3.3.2", + "yaml-language-server": "^0.8.0" + }, + "description": "Generating CI/CD pipelines to Azure from GitHub and Azure Repo", + "devDependencies": { + "@types/fs-extra": "4.0.5", + "@types/glob": "^7.1.1", + "@types/js-yaml": "^3.12.1", + "@types/mustache": "0.8.32", + "@types/node": "^7.0.43", + "@types/q": "1.5.0", + "@types/underscore": "1.8.9", + "ajv": "^6.9.1", + "assert": "1.4.1", + "chai": "^4.2.0", + "glob": "^7.1.6", + "nock": "^13.0.2", + "typescript-tslint-plugin": "^0.5.5" + }, + "displayName": "Deploy to Azure", + "extensionDependencies": [ + "ms-vscode.azure-account" + ], + "galleryBanner": { + "color": "#D4DCEC", + "theme": "light" + }, + "icon": "assets/deployToAzure.png", + "main": "./out/extension", + "name": "azure-deploy", + "scripts": { + "compile": "tsc -p ./ && node copyStaticFiles.js" + } +} diff --git a/src/configure/activate.ts b/src/configure/activate.ts deleted file mode 100644 index fc45460d..00000000 --- a/src/configure/activate.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, createApiProvider, IActionContext, registerCommand } from 'vscode-azureextensionui'; -import { AzureExtensionApi, AzureExtensionApiProvider } from 'vscode-azureextensionui/api'; -import { browsePipeline } from './browse'; -import { configurePipeline } from './configure'; -import { telemetryHelper } from './helper/telemetryHelper'; -import { AzureAccountExtensionExports, extensionVariables, IResourceNode } from './model/models'; -import { Messages } from './resources/messages'; - -export async function activateConfigurePipeline(): Promise { - let azureAccountExtension = vscode.extensions.getExtension("ms-vscode.azure-account"); - if (!azureAccountExtension) { - throw new Error(Messages.azureAccountExntesionUnavailable); - } - - if (!azureAccountExtension.isActive) { - await azureAccountExtension.activate(); - } - - extensionVariables.azureAccountExtensionApi = azureAccountExtension.exports; - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - registerCommand('configure-cicd-pipeline', async (actionContext: IActionContext, node: IResourceNode | vscode.Uri) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'configure-cicd-pipeline'); - await configurePipeline(node); - }); - - registerCommand('browse-cicd-pipeline', async (actionContext: IActionContext, node: AzureTreeItem) => { - // The code you place here will be executed every time your command is executed - telemetryHelper.initialize(actionContext, 'browse-cicd-pipeline'); - await browsePipeline(node); - }); - - return createApiProvider([ - { - configurePipelineApi: configurePipeline, - browsePipeline: browsePipeline, - apiVersion: "0.0.1" - }]); -} diff --git a/src/configure/browse.ts b/src/configure/browse.ts deleted file mode 100644 index 86ea50f9..00000000 --- a/src/configure/browse.ts +++ /dev/null @@ -1,100 +0,0 @@ -import * as vscode from 'vscode'; -import { AzureTreeItem, UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, ScmType } from './clients/azure/appServiceClient'; -import { getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import { AzureSession, extensionVariables, ParsedAzureResourceId } from './model/models'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; - -const Layer = 'browsePipeline'; - -export async function browsePipeline(node: AzureTreeItem): Promise { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!!node && !!node.fullId) { - let parsedAzureResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(node.fullId); - let session: AzureSession = await getSubscriptionSession(parsedAzureResourceId.subscriptionId); - let appServiceClient = new AppServiceClient(session.credentials, session.environment, session.tenantId, parsedAzureResourceId.subscriptionId); - await browsePipelineInternal(node.fullId, appServiceClient); - } - else { - throw new Error(Messages.didNotRecieveAzureResourceNodeToProcess); - } - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - extensionVariables.outputChannel.appendLine(error.message); - vscode.window.showErrorMessage(error.message); - telemetryHelper.setResult(Result.Failed, error); - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -async function browsePipelineInternal(resourceId: string, appServiceClient: AppServiceClient): Promise { - let siteConfig = await appServiceClient.getAppServiceConfig(resourceId); - let scmType = !!siteConfig && !!siteConfig.scmType && siteConfig.scmType.toLowerCase(); - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, scmType); - - if (scmType === ScmType.VSTSRM.toLowerCase()) { - await browseAzurePipeline(resourceId, appServiceClient); - } - else if (scmType === ScmType.GITHUBACTION.toLowerCase() && extensionVariables.enableGitHubWorkflow) { - await browseGitHubWorkflow(resourceId, appServiceClient); - } - else if (scmType === '' || scmType === ScmType.NONE.toLowerCase()) { - let deployToAzureAction = 'Deploy to Azure'; - let controlProvider = new ControlProvider(); - let result = await controlProvider.showInformationBox( - constants.BrowseNotAvailableConfigurePipeline, - Messages.browseNotAvailableConfigurePipeline, - deployToAzureAction); - - if (result === deployToAzureAction) { - vscode.commands.executeCommand('configure-pipeline', { fullId: resourceId }); - telemetryHelper.setTelemetry(TelemetryKeys.ClickedConfigurePipeline, 'true'); - } - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseAzurePipeline(resourceId: string, appServiceClient: AppServiceClient): Promise { - try { - let pipelineUrl = await appServiceClient.getAzurePipelineUrl(resourceId); - vscode.env.openExternal(vscode.Uri.parse(pipelineUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - catch (ex) { - telemetryHelper.logError(Layer, TracePoints.CorruptMetadataForVstsRmScmType, ex); - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function browseGitHubWorkflow(resourceId: string, appServiceClient: AppServiceClient): Promise { - let webAppSourceControl = await appServiceClient.getSourceControl(resourceId); - let webAppMetaData = await appServiceClient.getAppServiceMetadata(resourceId); - - if (!!webAppSourceControl && !!webAppSourceControl.properties && webAppSourceControl.properties.isGitHubAction) { - let url = `${webAppSourceControl.properties.repoUrl}/actions?query=${encodeURI("workflow:\"" + (!!webAppMetaData.properties.configName ? webAppMetaData.properties.configName : webAppMetaData.properties.configPath) + "\"")}`; - await vscode.env.openExternal(vscode.Uri.parse(url)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedExistingPipeline, 'true'); - } - else { - await openDeploymentCenter(resourceId, appServiceClient); - } -} - -async function openDeploymentCenter(resourceId: string, appServiceClient: AppServiceClient): Promise { - let deploymentCenterUrl: string = await appServiceClient.getDeploymentCenterUrl(resourceId); - await vscode.env.openExternal(vscode.Uri.parse(deploymentCenterUrl)); - telemetryHelper.setTelemetry(TelemetryKeys.BrowsedDeploymentCenter, 'true'); -} diff --git a/src/configure/clients/IProvisioningServiceClient.ts b/src/configure/clients/IProvisioningServiceClient.ts deleted file mode 100644 index f9579be4..00000000 --- a/src/configure/clients/IProvisioningServiceClient.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; - -export interface IProvisioningServiceClient { - createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise; - getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise; -} diff --git a/src/configure/clients/ITemplateServiceClient.ts b/src/configure/clients/ITemplateServiceClient.ts deleted file mode 100644 index 84717819..00000000 --- a/src/configure/clients/ITemplateServiceClient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ExtendedPipelineTemplate } from "../model/Contracts"; -import { StringMap } from "../model/models"; -import { TemplateInfo } from "../model/templateModels"; - -export interface ITemplateServiceClient { - getTemplates(body: RepositoryAnalysis): Promise; - getTemplateParameters(templateId: string): Promise; - getTemplateConfiguration(templateId: string, inputs: StringMap): Promise; - getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]>; - getTemplatesInfoByFilter(language: string, deployTargetFilter?: string, buildTargetFilter?: string): Promise; -} diff --git a/src/configure/clients/ProvisioningServiceClient.ts b/src/configure/clients/ProvisioningServiceClient.ts deleted file mode 100644 index 396d5811..00000000 --- a/src/configure/clients/ProvisioningServiceClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IServiceUrlDefinition, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { RestClient } from "./restClient"; - -export class ProvisioningServiceClient implements IProvisioningServiceClient { - private restClient: RestClient; - private serviceDefinition: IServiceUrlDefinition; - private defaultHeaders: { [propertyName: string]: string }; - private defaultParameters: { [propertyName: string]: string }; - private readonly pipelineProvisioningJob = "PipelineProvisioningJob"; - private readonly PEProvisioningServiceAPIVersion = "6.1-preview.1"; - - constructor(serviceDefinition: IServiceUrlDefinition, headers: { [propertyName: string]: string }, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.serviceDefinition = serviceDefinition; - this.defaultHeaders = headers; - if (this.serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.defaultParameters = { "api-version": this.PEProvisioningServiceAPIVersion }; - } - } - - public async createProvisioningConfiguration(provisioningConfiguration: ProvisioningConfiguration, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "POST", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - body: provisioningConfiguration, - serializationMapper: null, - deserializationMapper: null, - } - ); - } - - public async getProvisioningConfiguration(jobId: string, githubOrg: string, repositoryId: string): Promise { - const requestUrl = this.serviceDefinition.serviceUrl + githubOrg + "/" + repositoryId + "/" + this.pipelineProvisioningJob + "/" + jobId; - - return this.restClient.sendRequest({ - url: requestUrl, - method: "GET", - headers: this.defaultHeaders, - queryParameters: this.defaultParameters, - serializationMapper: null, - deserializationMapper: null, - } - ); - } -} diff --git a/src/configure/clients/TemplateServiceClientFactory.ts b/src/configure/clients/TemplateServiceClientFactory.ts deleted file mode 100644 index 69af3258..00000000 --- a/src/configure/clients/TemplateServiceClientFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { TemplateServiceClient } from "./github/TemplateServiceClient"; -import { ITemplateServiceClient } from "./ITemplateServiceClient"; -const UserAgent = "deploy-to-azure-vscode"; - -export class TemplateServiceClientFactory { - - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const serviceDefinition = await RemoteServiceUrlHelper.getTemplateServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, this.credentials, { - "Content-Type": "application/json; charset=utf-8" - }); - } else { - this.client = new TemplateServiceClient(serviceDefinition.serviceUrl, new TokenCredentials(this.githubPatToken, "token"), { - "User-Agent": UserAgent, - "Content-Type": "application/json; charset=utf-8" - }); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: ITemplateServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/azure/appServiceClient.ts b/src/configure/clients/azure/appServiceClient.ts deleted file mode 100644 index 781fbf40..00000000 --- a/src/configure/clients/azure/appServiceClient.ts +++ /dev/null @@ -1,178 +0,0 @@ -const uuid = require('uuid/v4'); -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import { WebSiteManagementClient } from 'azure-arm-website'; -import { Deployment, SiteConfigResource, StringDictionary } from 'azure-arm-website/lib/models'; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as Q from 'q'; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { ParsedAzureResourceId, TargetKind, WebAppSourceControl } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { TelemetryKeys } from '../../resources/telemetryKeys'; -import { AzureResourceClient } from './azureResourceClient'; - -export class AppServiceClient extends AzureResourceClient { - - private static resourceType = 'Microsoft.Web/sites'; - private webSiteManagementClient: WebSiteManagementClient; - private tenantId: string; - private environment: AzureEnvironment; - - constructor(credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string) { - super(credentials, subscriptionId); - this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId); - this.tenantId = tenantId; - this.environment = environment; - } - - public async getAppServiceResource(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async GetAppServices(filtersForResourceKind: TargetKind[]): Promise { - let resourceList: ResourceListResult = await this.getResourceList(AppServiceClient.resourceType); - if (!!filtersForResourceKind && filtersForResourceKind.length > 0) { - let filteredResourceList: ResourceListResult = []; - - resourceList.forEach((resource) => { - if (filtersForResourceKind.some((kind) => resource.kind === kind)) { - filteredResourceList.push(resource); - } - }); - - resourceList = filteredResourceList; - } - return resourceList; - } - - public async getWebAppPublishProfileXml(resourceId: string): Promise { - const deferred: Q.Deferred = Q.defer(); - const parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - let publishProfile = ''; - this.webSiteManagementClient.webApps.listPublishingProfileXmlWithSecrets(parsedResourceId.resourceGroup, parsedResourceId.resourceName, {}, (err, result, request, response) => { - if (err) { - deferred.reject(err); - } - response.on("data", (chunk: Buffer) => { - publishProfile += chunk; - }); - response.on('end', () => { - deferred.resolve(publishProfile); - }); - }); - return deferred.promise; - } - - public async getDeploymentCenterUrl(resourceId: string): Promise { - return `${this.environment.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`; - } - - public async getAzurePipelineUrl(resourceId: string): Promise { - let metadata = await this.getAppServiceMetadata(resourceId); - if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) { - return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']; - } - - throw new Error(Messages.cannotFindPipelineUrlInMetaDataException); - } - - public async getAppServiceConfig(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateScmType(resourceId: string): Promise { - let siteConfig = await this.getAppServiceConfig(resourceId); - siteConfig.scmType = ScmType.VSTSRM; - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig); - } - - public async getAppServiceMetadata(resourceId: string): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName); - } - - public async updateAppServiceMetadata(resourceId: string, metadata: StringDictionary): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata); - } - - public async publishDeploymentToAppService(resourceId: string, deploymentMessage: string, author: string = 'VSTS', deployer: string = 'VSTS'): Promise { - let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId); - - // create deployment object - let deploymentId = uuid(); - let deployment = this.createDeploymentObject(deploymentId, deploymentMessage, author, deployer); - return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment); - } - - public async setSourceControl(resourceId: string, properties: any): Promise { - await this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "PUT", - queryParameters: { - 'api-version': '2018-11-01' - }, - body: { - "properties": properties - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async getSourceControl(resourceId: string): Promise { - return this.webSiteManagementClient.sendRequest({ - url: `${this.environment.resourceManagerEndpointUrl}${resourceId}/sourcecontrols/web`, - method: "GET", - queryParameters: { - 'api-version': '2018-11-01' - }, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async isScmTypeSet(resourceId: string): Promise { - // Check for SCM type, if its value is set then a pipeline is already setup. - let siteConfig = await this.getAppServiceConfig(resourceId); - if (!!siteConfig.scmType && siteConfig.scmType.toLowerCase() !== ScmType.NONE.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.ScmType, siteConfig.scmType.toLowerCase()); - return true; - } - - return false; - } - - private createDeploymentObject(deploymentId: string, deploymentMessage: string, author: string, deployer: string): Deployment { - let deployment: Deployment = { - id: deploymentId, - status: 4, - author: author, - deployer: deployer, - message: deploymentMessage - }; - - return deployment; - } -} - -export enum ScmType { - VSTSRM = 'VSTSRM', - NONE = 'NONE', - GITHUBACTION = 'GITHUBACTION' -} - -export interface DeploymentMessage { - // tslint:disable-next-line: no-reserved-keywords - type: string; - message: string; -} - -export interface VSTSDeploymentMessage extends DeploymentMessage { - VSTSRM_BuildDefinitionWebAccessUrl?: string; - VSTSRM_ConfiguredCDEndPoint: string; - VSTSRM_BuildWebAccessUrl: string; -} \ No newline at end of file diff --git a/src/configure/clients/azure/armRestClient.ts b/src/configure/clients/azure/armRestClient.ts deleted file mode 100644 index a6d4218b..00000000 --- a/src/configure/clients/azure/armRestClient.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { AzureSession, ParsedAzureResourceId } from '../../model/models'; -import { RestClient } from '../restClient'; - -export class ArmRestClient { - private resourceManagerEndpointUrl: string; - private restClient: RestClient; - - public constructor(azureSession: AzureSession) { - this.resourceManagerEndpointUrl = azureSession.environment.resourceManagerEndpointUrl; - this.restClient = new RestClient(azureSession.credentials); - } - - public fetchArmData(endPointUri: string, httpMethod: string, body?: any) { - return this.sendRequest( - this.resourceManagerEndpointUrl + endPointUri, - httpMethod, - null, - body - ); - } - - public async getAcrCredentials(acrId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(acrId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerRegistry/registries/${parsedResourceId.resourceName}/listCredentials`, - 'POST', - '2019-05-01', - null); - } - - public async getAksKubeConfig(clusterId: string): Promise { - let parsedResourceId = new ParsedAzureResourceId(clusterId); - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential`, - 'POST', - '2020-01-01', - null); - } - - public async createResourceGroup(subscriptionId: string, resourceGroup: string, location: string ): Promise{ - return this.sendRequest( - this.resourceManagerEndpointUrl + `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}`, - 'PUT', - '2020-06-01', - { "location": location } - ); - } - - private async sendRequest(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.restClient.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/clients/azure/azureResourceClient.ts b/src/configure/clients/azure/azureResourceClient.ts deleted file mode 100644 index 3e2ed57a..00000000 --- a/src/configure/clients/azure/azureResourceClient.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { GenericResource, ResourceListResult } from 'azure-arm-resource/lib/resource/models'; -import * as ResourceManagementClient from 'azure-arm-resource/lib/resource/resourceManagementClient'; -import { ServiceClientCredentials } from 'ms-rest'; -import * as utils from 'util'; -import { TargetKind, TargetResourceType } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class AzureResourceClient { - - private azureRmClient: ResourceManagementClient.ResourceManagementClient; - - constructor(credentials: ServiceClientCredentials, subscriptionId: string) { - this.azureRmClient = new ResourceManagementClient.ResourceManagementClient(credentials, subscriptionId); - } - - public static validateTargetResourceType(resource: GenericResource): void { - if (!resource) { - throw new Error(Messages.azureResourceIsNull); - } - - switch (resource.type.toLowerCase()) { - case TargetResourceType.WebApp.toLowerCase(): - switch (resource.kind ? resource.kind.toLowerCase() : '') { - case TargetKind.LinuxApp: - case TargetKind.FunctionAppLinux: - case TargetKind.WindowsApp: - return; - case TargetKind.LinuxContainerApp: - case TargetKind.FunctionApp: - default: - throw new Error(utils.format(Messages.appKindIsNotSupported, resource.kind)); - } - case TargetResourceType.AKS.toLowerCase(): - return; - default: - throw new Error(utils.format(Messages.resourceTypeIsNotSupported, resource.type)); - } - } - - public async getResourceList(resourceType: string, followNextLink: boolean = true): Promise { - let resourceListResult: ResourceListResult = await this.azureRmClient.resources.list({ filter: `resourceType eq '${resourceType}'` }); - - if (followNextLink) { - let nextLink: string = resourceListResult.nextLink; - while (!!nextLink) { - let nextResourceListResult = await this.azureRmClient.resources.listNext(nextLink); - resourceListResult = resourceListResult.concat(nextResourceListResult); - nextLink = nextResourceListResult.nextLink; - } - } - - return resourceListResult; - } - - public async getResource(resourceId: string, apiVersion: string = '2019-10-01'): Promise { - let resource: GenericResource = await this.azureRmClient.resources.getById(resourceId, apiVersion); - return resource; - } - - public async updateCdSetupResourceTag(resource: GenericResource, repositoryId: string, branch: string, workflowFileName: string, commitId: string, namespaceName: string, apiVersion: string = '2019-10-01'): Promise { - let deploymentData: string = "GH" + ":" + repositoryId + ":" + branch + ":" + workflowFileName + ":" + workflowFileName + ":" + commitId + ":" + namespaceName + ":" + Date.now(); - resource.tags = resource.tags ? resource.tags : {}; - resource.tags = this.ComputeDeploymentResourceTags(resource.tags, deploymentData); - return await this.azureRmClient.resources.updateById(resource.id, apiVersion, resource); - } - - private ComputeDeploymentResourceTags(resourceTags: { [key: string]: string }, deploymentData: string) { - let startNewRow: boolean = true; - let storageColumn: boolean = true; //if storageColumn = true -> store in Tag Key field, else Tag Value field - let newTagKey: string = ""; - let newTagValue: string = ""; - - for (let tagName in resourceTags) { - //check if existing entry for resource tags - if (tagName.startsWith(DevopsInfoTagHeader)) { - // check if resource tags can be stored in tag Key field - if (tagName.length + deploymentData.length < MaxTagKeyLength) { - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - // check if resource tags can be stored in tag Value field - else if (resourceTags[tagName].length + deploymentData.length < MaxTagValueLength) { - storageColumn = false; - startNewRow = false; - newTagKey = tagName; - newTagValue = resourceTags[tagName]; - resourceTags[tagName] = null; - break; - } - } - } - - if (newTagKey) { - let tempResourceTags = {}; - for (let key in resourceTags) { - if (key !== newTagKey) { - tempResourceTags[key] = resourceTags[key]; - } - } - resourceTags = tempResourceTags; - } - - if (startNewRow) { - if (Object.keys(resourceTags).length > MaxTagsRow) { - throw new Error(Messages.EmptyTagRowUnavailable); - } - newTagKey = DevopsInfoTagHeader; - } - - if (storageColumn) { //Store resource tag in key field - newTagKey += deploymentData + ";"; - } - else { //Store resource tag in value field - newTagValue += deploymentData + ";"; - } - - resourceTags[newTagKey] = newTagValue; - return resourceTags; - } -} - -export let ApiVersions: Map = new Map(); -ApiVersions.set(TargetResourceType.ACR, '2019-05-01'); -ApiVersions.set(TargetResourceType.AKS, '2019-10-01'); - -const DevopsInfoTagHeader: string = "hidden-DevOpsInfo:"; -const MaxTagKeyLength: number = 512; -const MaxTagValueLength: number = 256; -const MaxTagsRow: number = 50; diff --git a/src/configure/clients/devOps/azureDevOpsClient.ts b/src/configure/clients/devOps/azureDevOpsClient.ts deleted file mode 100644 index f5b95de6..00000000 --- a/src/configure/clients/devOps/azureDevOpsClient.ts +++ /dev/null @@ -1,371 +0,0 @@ -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import * as Q from 'q'; -import * as util from 'util'; -import { sleepForMilliSeconds, stringCompareFunction } from "../../helper/commonHelper"; -import { telemetryHelper } from '../../helper/telemetryHelper'; -import { Build, BuildDefinition, Repository } from '../../model/azureDevOps'; -import { DevOpsProject, Organization } from '../../model/models'; -import { AzureDevOpsBaseUrl, ReservedHostNames } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { RestClient } from '../restClient'; - -export class AzureDevOpsClient { - private restClient: RestClient; - private listOrgPromise: Promise; - - constructor(credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.listOrgPromise = this.listOrganizations(); - } - - public async sendRequest(urlBasedRequestPrepareOptions: UrlBasedRequestPrepareOptions): Promise { - if (urlBasedRequestPrepareOptions.headers) { - urlBasedRequestPrepareOptions.headers['X-TFS-Session'] = telemetryHelper.getJourneyId(); - } - else { - urlBasedRequestPrepareOptions.headers = { 'X-TFS-Session': telemetryHelper.getJourneyId() }; - } - - return this.restClient.sendRequest(urlBasedRequestPrepareOptions); - } - - public async createOrganization(organizationName: string): Promise { - return this.sendRequest({ - url: "https://app.vsaex.visualstudio.com/_apis/HostAcquisition/collections", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "collectionName": organizationName, - "api-version": "4.0-preview.1", - "preferredRegion": "CUS" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createProject(organizationName: string, projectName: string): Promise { - let collectionUrl = `https://dev.azure.com/${organizationName}`; - - return this.sendRequest({ - url: `${collectionUrl}/_apis/projects`, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - queryParameters: { - "api-version": "5.0" - }, - body: { - "name": projectName, - "visibility": 0, - "capabilities": { - "versioncontrol": { "sourceControlType": "Git" }, - "processTemplate": { "templateTypeId": "adcc42ab-9882-485e-a3ed-7678f01f66bc" } - } - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((operation) => { - if (operation.url) { - return this.monitorOperationStatus(operation.url); - } - else { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operation.message)); - } - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = this.getUserData() - .then((connectionData) => { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/accounts", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "memberId": connectionData.authenticatedUser.id, - "api-version": "5.0", - "properties": "Microsoft.VisualStudio.Services.Account.ServiceUrl.00025394-6065-48ca-87d9-7f5672854ef7" - }, - deserializationMapper: null, - serializationMapper: null - }); - }) - .then((organizations) => { - let organizationList: Array = organizations.value; - organizationList = organizationList.sort((org1, org2) => stringCompareFunction(org1.accountName, org2.accountName)); - return organizationList; - }); - } - - return this.listOrgPromise; - } - - public async listProjects(organizationName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects`; - let response = await this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json" - }, - method: "GET", - queryParameters: { - "includeCapabilities": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - - let projects: Array = []; - if (response.value && response.value.length > 0) { - projects = response.value.map((project) => { - return { id: project.id, name: project.name }; - }); - projects = projects.sort((proj1, proj2) => stringCompareFunction(proj1.name, proj2.name)); - } - return projects; - } - - public async getRepository(organizationName: string, projectName: string, repositoryName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/git/repositories/${repositoryName}`; - - return this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - }, - method: "GET", - queryParameters: { - "api-version": "5.0" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createBuildDefinition(organizationName: string, buildDefinition: BuildDefinition): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${buildDefinition.project.id}/_apis/build/definitions`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.0-preview.7;" - }, - body: buildDefinition, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async queueBuild(organizationName: string, build: Build): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${build.project.id}/_apis/build/builds`; - - return this.sendRequest({ - url: url, - method: "POST", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - body: build, - serializationMapper: null, - deserializationMapper: null - }); - } - - public async validateOrganizationName(organizationName: string): Promise { - let deferred = Q.defer(); - let accountNameRegex = new RegExp(/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$|^[a-zA-Z]$/); - - if (!organizationName || /^\\s/.test(organizationName) || /\\s$/.test(organizationName) || organizationName.indexOf("-") === 0 || !accountNameRegex.test(organizationName)) { - deferred.resolve(Messages.organizationNameStaticValidationMessage); - } - else if (ReservedHostNames.indexOf(organizationName) >= 0) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - else { - let url = `https://app.vsaex.visualstudio.com/_apis/HostAcquisition/NameAvailability/${organizationName}`; - - this.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "api-version=5.0-preview.1" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }) - .then((response) => { - if (response.name === organizationName && !response.isAvailable) { - deferred.resolve(util.format(Messages.organizationNameReservedMessage, organizationName)); - } - deferred.resolve(""); - }) - .catch(() => { - deferred.resolve(""); - }); - } - return deferred.promise; - } - - public async getProjectIdFromName(organizationName: string, projectName: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/_apis/projects/${projectName}`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;api-version=5.2-preview.5;" - }, - queryParameters: { - "api-version": "5.0", - "includeCapabilities": false - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((project) => { - return project && project.id; - }); - } - - public async getOrganizationIdFromName(organizationName: string) { - let organization = (await this.listOrgPromise).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organizationName) { - organization = (await this.listOrganizations(true)).find((org) => { - return org.accountName.toLowerCase() === organizationName.toLowerCase(); - }); - - if (!organization) { - throw new Error(Messages.cannotFindOrganizationWithName); - } - } - - return organization.accountId; - } - - public getOldFormatBuildDefinitionUrl(accountName: string, projectName: string, buildDefinitionId: number) { - return `https://${accountName}.visualstudio.com/${projectName}/_build?definitionId=${buildDefinitionId}&_a=summary`; - } - - public getOldFormatBuildUrl(accountName: string, projectName: string, buildId: string) { - return `https://${accountName}.visualstudio.com/${projectName}/_build/results?buildId=${buildId}&view=results`; - } - - private getUserData(): Promise { - return this.getConnectionData() - .catch(() => { - return this.createUserProfile() - .then(() => { - return this.getConnectionData(); - }); - }); - } - - private getConnectionData(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/connectiondata", - headers: { - "Content-Type": "application/json" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - private createUserProfile(): Promise { - return this.sendRequest({ - url: "https://app.vssps.visualstudio.com/_apis/_AzureProfile/CreateProfile", - headers: { - "Content-Type": "application/json" - }, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - } - - private async monitorOperationStatus(operationUrl: string): Promise { - let retryCount = 0; - let operationResult: any; - - while (retryCount < 30) { - operationResult = await this.getOperationResult(operationUrl); - let result = operationResult.status.toLowerCase(); - if (result === "succeeded") { - return; - } - else if (result === "failed") { - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, operationResult.detailedMessage)); - } - else { - retryCount++; - await sleepForMilliSeconds(2000); - } - } - throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, - (operationResult && operationResult.detailedMessage) || Messages.operationTimedOut)); - } - - private async getOperationResult(operationUrl: string): Promise { - return this.sendRequest({ - url: operationUrl, - queryParameters: { - "api-version": "5.0" - }, - method: "GET", - deserializationMapper: null, - serializationMapper: null - }); - } - - public getAgentQueues(organizationName: string, projectName: string): Promise> { - let url = `${AzureDevOpsBaseUrl}/${organizationName}/${projectName}/_apis/distributedtask/queues`; - - return this.sendRequest({ - url: url, - method: "GET", - headers: { - "Accept": "application/json;" - }, - queryParameters: { - "api-version": "5.1-preview.1" - }, - serializationMapper: null, - deserializationMapper: null - }) - .then((response) => { - return response.value; - }); - } - - public createRepository(organizationName: string, projectId: string, repositoryName: string): Promise { - return this.sendRequest({ - url: `${AzureDevOpsBaseUrl}/${organizationName}/${projectId}/_apis/git/repositories`, - headers: { - 'Content-Type': 'application/json' - }, - method: 'POST', - queryParameters: { - 'api-version': '5.1' - }, - body: { - 'name': repositoryName - }, - deserializationMapper: null, - serializationMapper: null - }); - } -} diff --git a/src/configure/clients/devOps/serviceConnectionClient.ts b/src/configure/clients/devOps/serviceConnectionClient.ts deleted file mode 100644 index 28ddf0a3..00000000 --- a/src/configure/clients/devOps/serviceConnectionClient.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AadApplication, ParsedAzureResourceId } from '../../model/models'; -import { AzureDevOpsBaseUrl } from "../../resources/constants"; -import { AzureDevOpsClient } from './azureDevOpsClient'; - - -export class ServiceConnectionClient { - private azureDevOpsClient: AzureDevOpsClient; - private organizationName: string; - private projectName: string; - - constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - this.organizationName = organizationName; - this.projectName = projectName; - } - - public async createGitHubServiceConnection(endpointName: string, gitHubPat: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest( - { - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "accessToken": gitHubPat - }, - "scheme": "PersonalAccessToken" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "github", - "url": "http://github.com" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzureSPNServiceConnection(endpointName: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "authenticationType": "spnKey", - "scope": scope, - "serviceprincipalid": aadApp.appId, - "serviceprincipalkey": aadApp.secret, - "tenantid": tenantId - }, - "scheme": "ServicePrincipal" - }, - "data": { - "creationMode": "Manual", - "subscriptionId": subscriptionId, - "subscriptionName": subscriptionId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createKubernetesServiceConnectionWithKubeConfig(endpointName: string, kubeconfig: string, apiServerAddress: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "kubeconfig": kubeconfig - }, - "scheme": "Kubernetes" - }, - "data": { - "authorizationType": "Kubeconfig", - "acceptUntrustedCerts": "true", - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "kubernetes", - "url": apiServerAddress - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createContainerRegistryServiceConnection(endpointName: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "registry": registryUrl, - "username": registryUsername, - "password": registryPassword, - "email": "" - }, - "scheme": "UsernamePassword" - }, - "data": { - "registryType": "Others" - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "dockerregistry", - "url": registryUrl - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async createAzurePublishProfileServiceConnection(endpointName: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints`; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "POST", - body: { - "administratorsGroup": null, - "authorization": { - "parameters": { - "publishProfile": publishProfile, - "tenantid": tenantId - }, - "scheme": "PublishProfile" - }, - "data": { - "subscriptionName": parsedResourceId.subscriptionId, - "resourceId": resourceId - }, - "description": "", - "groupScopeId": null, - "name": endpointName, - "operationStatus": null, - "readersGroup": null, - "type": "azurerm", - "url": "https://management.azure.com/" - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getEndpointStatus(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/serviceendpoint/endpoints/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.2;excludeUrls=true" - }, - method: "Get", - deserializationMapper: null, - serializationMapper: null - }); - } - - public async authorizeEndpointForAllPipelines(endpointId: string): Promise { - let url = `${AzureDevOpsBaseUrl}/${this.organizationName}/${this.projectName}/_apis/pipelines/pipelinePermissions/endpoint/${endpointId}`; - - return this.azureDevOpsClient.sendRequest({ - url: url, - headers: { - "Content-Type": "application/json", - "Accept": "application/json;api-version=5.1-preview.1;excludeUrls=true;enumsAsNumbers=true;msDateFormat=true;noArrayWrap=true" - }, - method: "PATCH", - body: { - "allPipelines": { - "authorized": true, - "authorizedBy": null, - "authorizedOn": null - }, - "pipelines": null, - "resource": { - "id": endpointId, - "type": "endpoint" - } - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} diff --git a/src/configure/clients/github/TemplateServiceClient.ts b/src/configure/clients/github/TemplateServiceClient.ts deleted file mode 100644 index 9b348e5a..00000000 --- a/src/configure/clients/github/TemplateServiceClient.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { RepositoryAnalysis } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from "ms-rest"; -import { ExtendedPipelineTemplate } from "../../model/Contracts"; -import { StringMap } from "../../model/models"; -import { TemplateInfo } from "../../model/templateModels"; -import { ITemplateServiceClient } from "../ITemplateServiceClient"; -import { RestClient } from "../restClient"; - -export class TemplateServiceClient implements ITemplateServiceClient { - private restClient: RestClient; - private templateServiceUri: string; - private headers; - private readonly apiVersion = "6.0-preview.1"; - private readonly extendedPipelineTemplateResource = "ExtendedPipelineTemplates"; - private readonly templatesInfoResource = "TemplatesInfo"; - private readonly templateAssetFilesResource = "TemplateAssetFiles"; - private readonly hideKey = "vside"; - - constructor(url: string, creds?: ServiceClientCredentials, headers?) { - this.restClient = new RestClient(creds); - this.templateServiceUri = url; - this.headers = headers; - } - - public async getTemplatesInfoByFilter(language: string, deployTarget: string, buildTarget: string): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'GET', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'languageFilter': language, - 'deployTargetFilter': deployTarget, - 'buildTargetFilter': buildTarget, - 'hideKey': this.hideKey - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplates(body: RepositoryAnalysis): Promise { - return this.restClient.sendRequest( - { - url: this.templateServiceUri + this.templatesInfoResource, - method: 'POST', - headers: this.headers, - queryParameters: { - 'api-version': this.apiVersion, - 'hideKey': this.hideKey - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateParameters(templateId: string): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'parameters', - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateConfiguration(templateId: string, inputs: StringMap): Promise { - const requestUri = this.templateServiceUri + this.extendedPipelineTemplateResource; - return this.restClient.sendRequest( - { - url: requestUri, - method: 'POST', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'templatePartToGet': 'configuration', - 'api-version': this.apiVersion - }, - body: inputs, - deserializationMapper: null, - serializationMapper: null - }); - } - - public async getTemplateFile(templateId: string, fileName: string): Promise<{ id: string, content: string }[]> { - const requestUri = this.templateServiceUri + this.templateAssetFilesResource; - - return this.restClient.sendRequest( - { - url: requestUri, - method: 'GET', - headers: this.headers, - queryParameters: { - 'templateId': templateId, - 'fileNames': fileName, - 'api-version': this.apiVersion - }, - deserializationMapper: null, - serializationMapper: null - }); - } - -} \ No newline at end of file diff --git a/src/configure/clients/github/githubClient.ts b/src/configure/clients/github/githubClient.ts deleted file mode 100644 index 082d5d6b..00000000 --- a/src/configure/clients/github/githubClient.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { stringCompareFunction } from "../../helper/commonHelper"; -import { GitHubProvider } from "../../helper/gitHubHelper"; -import { SodiumLibHelper } from '../../helper/sodium/SodiumLibHelper'; -import { GitHubOrganization, GitHubRepo } from '../../model/models'; -import { Messages } from '../../resources/messages'; -import { WhiteListedError } from '../../utilities/utilities'; -import { IUrlBasedRequestPrepareOptions2, RestClient } from "../restClient"; - -const UserAgent = "deploy-to-azure-vscode"; - -export class GithubClient { - - private patToken: string; - private url: string; - private listOrgPromise: Promise; - - constructor(patToken: string, remoteUrl: string) { - this.patToken = patToken; - this.url = remoteUrl; - } - - public async setRepoUrl(repoUrl: string) { - this.url = repoUrl; - } - - public async createOrUpdateGithubSecret(secretName: string, body: string): Promise { - const secretKeyObject: IGitHubSecretKey = await this._getGitHubSecretKey(); - const sodiumObj = new SodiumLibHelper(secretKeyObject.key); - const encryptedBytes: Uint8Array = sodiumObj.encrypt(body); - const encryptedBytesAsString: string = SodiumLibHelper.convertUint8ArrayToString(encryptedBytes); - const encryptedEncodedText = SodiumLibHelper.encodeToBase64(encryptedBytesAsString); - await this._setGithubSecret(secretName, secretKeyObject.key_id, encryptedEncodedText); - } - - public async createGithubRepo(orgName: string, repoName: string, isUserAccount: boolean = false): Promise { - const Url = isUserAccount ? "https://api.github.com/user/repos" : "https://api.github.com/orgs/" + orgName + "/repos"; - return this._sendRequest({ - url: Url, - headers: { - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent - }, - method: 'POST', - body: { - name: repoName, - description: "Repo created from VScode extension 'Deploy to Azure'", - homepage: "https://github.com", - private: true, - has_issues: true, - has_projects: true, - has_wiki: true - }, - deserializationMapper: null, - serializationMapper: null, - }) - .then((detail: GitHubRepo) => { - return detail; - }).catch((error) => { - if (error.response.statusCode === 422) { - return null; - } - throw new Error(JSON.parse(error.response.body).message); - }); - } - - public async listOrganizations(forceRefresh?: boolean): Promise { - if (!this.listOrgPromise || forceRefresh) { - this.listOrgPromise = Promise.all([ - this._sendRequest({ - url: "https://api.github.com/user/orgs", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }), - this._sendRequest({ - url: "https://api.github.com/user", - method: 'GET', - headers: { - "Authorization": "Bearer " + this.patToken, - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Accept": "*/*" - }, - deserializationMapper: null, - serializationMapper: null - }) - ]) - .then(([organizations, userInfo]) => { - (userInfo as GitHubOrganization).isUserAccount = true; - return ((organizations as GitHubOrganization[]).concat(userInfo as GitHubOrganization)).sort((org1, org2) => stringCompareFunction(org1.login, org2.login)); - }); - } - return this.listOrgPromise; - } - - public async _getGitHubSecretKey(): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/public-key", - method: 'GET', - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - serializationMapper: null, - deserializationMapper: null - }; - return (await this._sendRequest(request)) as IGitHubSecretKey; - } - - public async _setGithubSecret(secretName: string, key_id: string, encrypted_secret: string): Promise { - const request = { - url: GitHubProvider.getFormattedGitHubApiUrlBase(this.url) + "/actions/secrets/" + secretName, - headers: { - "User-Agent": UserAgent, - "Content-Type": "application/json", - "Authorization": "Bearer " + this.patToken, - "Accept": "*/*" - }, - method: "PUT", - deserializationMapper: null, - serializationMapper: null, - body: { - encrypted_value: encrypted_secret, - key_id: key_id - } - }; - await this._sendRequest(request); - } - - private _sendRequest(request: IUrlBasedRequestPrepareOptions2): Promise<{}> { - const restClient = new RestClient(); - return restClient.sendRequest({ ...request, returnFullResponseForFailure: true }) - .catch((error) => { - if (error.response.statusCode === 401 || error.response.statusCode === 403) { - throw new WhiteListedError(Messages.GitHubPatInvalid); - } - - throw error; - }); - } -} - -export interface IGitHubSecretKey { - key_id: string; - key: string; -} diff --git a/src/configure/clients/modaRepositoryAnalysisClient.ts b/src/configure/clients/modaRepositoryAnalysisClient.ts deleted file mode 100644 index cea8e498..00000000 --- a/src/configure/clients/modaRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { RestClient } from "typed-rest-client"; -import vscodeUri from "vscode-uri"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; - -export class ModaRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private githubPat: string; - private pathUrl: string; - - constructor(url: string, githubPat: string) { - const u = vscodeUri.parse(url); - this.restClient = new RestClient("deploy-to-azure", u.scheme + "://" + u.authority); - this.pathUrl = u.path; - this.githubPat = githubPat; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - const requestOptions = { - acceptHeader: "application/json", - additionalHeaders: { - "Authorization": "Bearer " + this.githubPat - } - }; - return ((await this.restClient.create(this.pathUrl, body, requestOptions)).result); - } -} diff --git a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts b/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts deleted file mode 100644 index ba30c3dc..00000000 --- a/src/configure/clients/portalExtensionRepositoryAnalysisClient.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials, UrlBasedRequestPrepareOptions } from "ms-rest"; -import { IRepositoryAnalysisClient } from "./repositoryAnalyisClient"; -import { RestClient } from "./restClient"; - -export class PortalExtensionRepositoryAnalysisClient implements IRepositoryAnalysisClient { - private restClient: RestClient; - private url: string; - constructor(url: string, credentials: ServiceClientCredentials) { - this.restClient = new RestClient(credentials); - this.url = url; - } - - public async getRepositoryAnalysis(body: SourceRepository): Promise { - - return this.restClient.sendRequest({ - url: this.url, - headers: { - "Content-Type": "application/json" - }, - method: "POST", - body: body, - serializationMapper: null, - deserializationMapper: null - }); - } -} diff --git a/src/configure/clients/provisioningServiceClientFactory.ts b/src/configure/clients/provisioningServiceClientFactory.ts deleted file mode 100644 index 3e8288ef..00000000 --- a/src/configure/clients/provisioningServiceClientFactory.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ServiceClientCredentials, TokenCredentials } from "ms-rest"; -import { RemoteServiceUrlHelper, ServiceFramework } from "../helper/remoteServiceUrlHelper"; -import { Messages } from '../resources/messages'; -import { IProvisioningServiceClient } from "./IProvisioningServiceClient"; -import { ProvisioningServiceClient } from "./ProvisioningServiceClient"; - - -export class ProvisioningServiceClientFactory { - public static async getClient(): Promise { - if (!!this.client) { - return this.client; - } - - if (!this.githubPatToken || !this.credentials) { - throw new Error(Messages.UndefinedClientCredentials); - } - - const defaultHeaders: { [propertyName: string]: string } = { "Content-Type": "application/json" }; - const serviceDefinition = await RemoteServiceUrlHelper.getProvisioningServiceDefinition(); - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - defaultHeaders["X-GITHUB-TOKEN"] = "token " + this.githubPatToken; - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, this.credentials); - } else { - this.client = new ProvisioningServiceClient(serviceDefinition, defaultHeaders, new TokenCredentials(this.githubPatToken, "token")); - } - - return this.client; - } - - public static initialize(credentials: ServiceClientCredentials, githubPatToken: string): void { - this.client = null; - this.credentials = credentials; - this.githubPatToken = githubPatToken - } - - private static client: IProvisioningServiceClient; - private static credentials: ServiceClientCredentials; - private static githubPatToken: string; -} diff --git a/src/configure/clients/repositoryAnalyisClient.ts b/src/configure/clients/repositoryAnalyisClient.ts deleted file mode 100644 index f097b9fb..00000000 --- a/src/configure/clients/repositoryAnalyisClient.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; - -export interface IRepositoryAnalysisClient { - getRepositoryAnalysis(body: SourceRepository): Promise; -} diff --git a/src/configure/clients/restClient.ts b/src/configure/clients/restClient.ts deleted file mode 100644 index 34ec4070..00000000 --- a/src/configure/clients/restClient.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { PathTemplateBasedRequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, UrlBasedRequestPrepareOptions } from "ms-rest"; - -export interface IPathTemplateBasedRequestPrepareOptions2 extends PathTemplateBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export interface IUrlBasedRequestPrepareOptions2 extends UrlBasedRequestPrepareOptions { - returnFullResponseForFailure?: boolean; -} - -export class RestClient extends ServiceClient { - constructor(credentials?: ServiceClientCredentials, options?: ServiceClientOptions) { - super(credentials, options); - } - - public sendRequest(options: IPathTemplateBasedRequestPrepareOptions2 | IUrlBasedRequestPrepareOptions2): Promise { - return new Promise((resolve, reject) => { - super.sendRequestWithHttpOperationResponse(options) - .then((response) => { - if (response.response.statusCode >= 300) { - if (options.returnFullResponseForFailure === true) { - reject(response); - } - else { - reject(response.body); - } - } - resolve(response.body); - }) - .catch((error) => { - reject(error); - }); - }); - } - - public sendRequest2(url: string, httpMethod: string, apiVersion: string, body?: any): Promise { - return this.sendRequest( - { - url: url, - method: httpMethod, - headers: { - "Content-Type": "application/json; charset=utf-8" - }, - queryParameters: { - 'api-version': apiVersion - }, - body: body, - deserializationMapper: null, - serializationMapper: null - }); - } -} \ No newline at end of file diff --git a/src/configure/configure.ts b/src/configure/configure.ts deleted file mode 100644 index e97dd64e..00000000 --- a/src/configure/configure.ts +++ /dev/null @@ -1,766 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings, RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient } from './clients/azure/appServiceClient'; -import { AzureResourceClient } from './clients/azure/azureResourceClient'; -import { ProvisioningServiceClientFactory } from './clients/provisioningServiceClientFactory'; -import { TemplateServiceClientFactory } from './clients/TemplateServiceClientFactory'; -import { Configurer } from './configurers/configurerBase'; -import { ConfigurerFactory } from './configurers/configurerFactory'; -import { ProvisioningConfigurer } from './configurers/provisioningConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkflowConfigurer'; -import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; -import { AssetHandler } from './helper/AssetHandler'; -import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; -import { ControlProvider } from './helper/controlProvider'; -import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; -import { GitHubProvider } from './helper/gitHubHelper'; -import { LocalGitRepoHelper } from './helper/LocalGitRepoHelper'; -import { RepoAnalysisHelper } from './helper/repoAnalysisHelper'; -import { Result, telemetryHelper } from './helper/telemetryHelper'; -import * as templateHelper from './helper/templateHelper'; -import { TemplateParameterHelper } from './helper/templateParameterHelper'; -import { ConfigurationStage } from './model/Contracts'; -import { extensionVariables, GitBranchDetails, GitRepositoryParameters, IResourceNode, MustacheContext, ParsedAzureResourceId, PipelineType, QuickPickItemWithData, RepositoryProvider, SourceOptions, StringMap, TargetResourceType, WizardInputs } from './model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration, provisioningMode } from './model/provisioningConfiguration'; -import { LocalPipelineTemplate, PipelineTemplate, RemotePipelineTemplate, TemplateAssetType, TemplateType } from './model/templateModels'; -import * as constants from './resources/constants'; -import { Messages } from './resources/messages'; -import { TelemetryKeys } from './resources/telemetryKeys'; -import { TracePoints } from './resources/tracePoints'; -import { InputControlProvider } from './templateInputHelper/InputControlProvider'; -import { Utilities, WhiteListedError } from './utilities/utilities'; - -const uuid = require('uuid/v4'); - -const Layer: string = 'configure'; -export let UniqueResourceNameSuffix: string = uuid().substr(0, 5); - -export async function configurePipeline(node: IResourceNode | vscode.Uri) { - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - try { - if (!(await extensionVariables.azureAccountExtensionApi.waitForLogin())) { - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginRequired, 'true'); - - const loginOption = await vscode.window.showInformationMessage(Messages.azureLoginRequired, Messages.signInLabel, Messages.signUpLabel); - if (loginOption && loginOption.toLowerCase() === Messages.signInLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignIn'); - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.waitForAzureSignIn }, - async () => { - await vscode.commands.executeCommand("azure-account.login"); - await extensionVariables.azureAccountExtensionApi.waitForSubscriptions(); - }); - } - else if (loginOption && loginOption.toLowerCase() === Messages.signUpLabel.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.AzureLoginOption, 'SignUp'); - await vscode.commands.executeCommand("azure-account.createAccount"); - return; - } - else { - const error = new UserCancelledError(Messages.azureLoginRequired); - throw error; - } - } - - const orchestrator = new Orchestrator(); - await orchestrator.configure(node); - } - catch (error) { - if (!(error instanceof UserCancelledError)) { - vscode.window.showErrorMessage(error.message); - extensionVariables.outputChannel.appendLine(error.message); - if (error instanceof WhiteListedError) { - telemetryHelper.setTelemetry(TelemetryKeys.IsErrorWhitelisted, "true"); - telemetryHelper.setResult(Result.Succeeded, error); - } else { - telemetryHelper.setResult(Result.Failed, error); - } - } - else { - telemetryHelper.setResult(Result.Canceled, error); - } - } - }, TelemetryKeys.CommandExecutionDuration); -} - -class Orchestrator { - private inputs: WizardInputs; - private localGitRepoHelper: LocalGitRepoHelper; - private azureResourceClient: AzureResourceClient; - private workspacePath: string; - private controlProvider: ControlProvider; - private continueOrchestration: boolean = true; - private context: StringMap = {}; - private pipelineType: PipelineType; - - public constructor() { - this.inputs = new WizardInputs(); - this.controlProvider = new ControlProvider(); - UniqueResourceNameSuffix = uuid().substr(0, 5); - this.context['isResourceAlreadySelected'] = false; - this.context['resourceId'] = ''; - } - - public async configure(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setCurrentStep('GetAllRequiredInputs'); - await this.getInputs(node); - if (this.continueOrchestration) { - if (this.doesLanguageAndTargetSupportRemoteProvisioning()) { - return await this.configurePipelineRemotely(); - } - return this.ConfigurePipelineLocally(); - } - } - - private doesLanguageAndTargetSupportRemoteProvisioning(): boolean { - // This check is to enable for all remote repository webapps and aks flows to use remote provisioning service. - // Both template type as remote and remote url check is required because remote provisioning is only applicable for remote templates and there are scenario where template selected is remote but repo is not remote (in cases where resource is already selected) - return extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && - (this.inputs.targetResource.resource.type === TargetResourceType.AKS || this.inputs.targetResource.resource.type === TargetResourceType.WebApp) && !!this.inputs.sourceRepository.remoteUrl && this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE; - } - - private async getAzureResource(targetType: TargetResourceType) { - const azureResourceSelector = ResourceSelectorFactory.getAzureResourceSelector(targetType); - this.inputs.targetResource.resource = await azureResourceSelector.getAzureResource(this.inputs); - this.azureResourceClient = ResourceSelectorFactory.getAzureResourceClient(targetType, this.inputs.azureSession.credentials, - this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); - if (targetType === TargetResourceType.WebApp) { - this.context['resourceId'] = this.inputs.targetResource.resource.id; - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); - } - } - - private async selectTemplate(resource: GenericResource): Promise { - switch (resource.type) { - case TargetResourceType.AKS: - if (extensionVariables.remoteConfigurerEnabled === true && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && !!this.inputs.sourceRepository.remoteUrl) { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } else { - this.inputs.pipelineConfiguration.template = this.inputs.potentialTemplates.find((template) => template.templateType === TemplateType.LOCAL); - } - if (this.inputs.pipelineConfiguration.template === undefined) { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - case TargetResourceType.WebApp: - let shortlistedTemplates = []; - shortlistedTemplates = this.inputs.potentialTemplates.filter((template) => template.targetKind === resource.kind); - if (!!shortlistedTemplates && shortlistedTemplates.length > 1) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates.find((template) => template.templateType === TemplateType.REMOTE); - } - else if (!!shortlistedTemplates) { - this.inputs.pipelineConfiguration.template = shortlistedTemplates[0]; - } - else { - telemetryHelper.logError(Layer, TracePoints.TemplateNotFound, new Error(Messages.TemplateNotFound + " RepoId: " + this.inputs.sourceRepository.repositoryId)); - throw new Error(Messages.TemplateNotFound); - } - break; - - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - private setPipelineType() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - this.pipelineType = PipelineType.GitHubPipeline; - } else { - this.pipelineType = PipelineType.AzurePipeline; - } - } - - private isResourceAlreadySelected(): boolean { - return this.context['isResourceAlreadySelected']; - } - - private async getInputs(node: IResourceNode | vscode.Uri): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseGithubForCreatingNewRepository, - vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository')); - telemetryHelper.setTelemetry(TelemetryKeys.FF_UseAzurePipelinesForGithub, - vscode.workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub')); - - await this.analyzeNode(node); - - if (this.continueOrchestration) { - await this.getSourceRepositoryDetails(); - if (!this.inputs.azureSession) { - this.inputs.azureSession = await getAzureSession(); - } - - // Right click scenario not supported for Azure and local repo - if (this.isResourceAlreadySelected()) { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.AzureRepos || extensionVariables.isLocalRepo) { - throw new WhiteListedError(Messages.GithubRepoRequired); - } else if (!extensionVariables.enableGitHubWorkflow) { - // For github repo, we create a github pipeline - extensionVariables.enableGitHubWorkflow = true; - } - } - - const repoAnalysisResult = await this.getRepositoryAnalysis(); - - this.initializeClientFactories(); - this.setPipelineType(); - await this.getTemplatesByRepoAnalysis(repoAnalysisResult); - try { - if (!this.isResourceAlreadySelected()) { - await this.getAzureSubscription(); - await this.getAzureResource(this.getSelectedPipelineTargetType()); - } - - this.selectTemplate(this.inputs.targetResource.resource); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplate, this.inputs.pipelineConfiguration.template.label); - telemetryHelper.setTelemetry(TelemetryKeys.SelectedTemplateType, (this.inputs.pipelineConfiguration.template.templateType).toString()); - - await this.updateRepositoryAnalysisApplicationSettings(repoAnalysisResult); - - await this.getTemplateParameters(); - } - catch (err) { - if (err.message === Messages.setupAlreadyConfigured) { - this.continueOrchestration = false; - return; - } - else { - throw err; - } - } - } - } - - private async getTemplateParameters() { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - const extendedPipelineTemplate = await templateHelper.getTemplateParameters(template.id); - template.attributes = extendedPipelineTemplate.attributes; - template.parameters = extendedPipelineTemplate.parameters; - const controlProvider = new InputControlProvider(this.inputs.azureSession, extendedPipelineTemplate, this.context); - this.inputs.pipelineConfiguration.params = await controlProvider.getAllPipelineTemplateInputs(); - } - else if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS && this.inputs.sourceRepository.repositoryId != RepositoryProvider.Github) { - const templateParameterHelper = await new TemplateParameterHelper(); - const template = this.inputs.pipelineConfiguration.template as LocalPipelineTemplate; - await templateParameterHelper.setParameters(template.parameters, this.inputs); - } - } - - private async getGithubPatToken(): Promise { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - this.inputs.githubPATToken = await this.controlProvider.showInputBox(constants.GitHubPat, { - placeHolder: Messages.enterGitHubPat, - prompt: Messages.githubPatTokenHelpMessage, - validateInput: (inputValue) => { - return !inputValue ? Messages.githubPatTokenErrorMessage : null; - } - }); - } - } - - private async getRepositoryAnalysis() { - if (this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - await this.getGithubPatToken(); - return await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.AnalyzingRepo }, - () => telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - return await new RepoAnalysisHelper(this.inputs.azureSession, this.inputs.githubPATToken).getRepositoryAnalysis( - this.inputs.sourceRepository, this.inputs.pipelineConfiguration.workingDirectory.split('/').join('\\')); - }, TelemetryKeys.RepositoryAnalysisDuration) - ); - } - return null; - } - - private getSelectedPipelineTargetType(): TargetResourceType { - return this.inputs.potentialTemplates[0].targetType; - } - - private async analyzeNode(node: IResourceNode | vscode.Uri): Promise { - if (!!node) { - const folderNode = node as vscode.Uri; - if (!!(folderNode.fsPath)) { - // right click on a folder - this.workspacePath = folderNode.fsPath; - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - } else if (await this.extractAzureResourceFromNode(node as IResourceNode)) { - // right click on a resource - this.context['isResourceAlreadySelected'] = true; - this.context['resourceId'] = this.inputs.targetResource.resource.id; - } - } - } - - private async getSourceRepositoryDetails(): Promise { - try { - if (!this.workspacePath) { // This is to handle when we have already identified the repository details. - await this.setWorkspace(); - } - await this.getGitDetailsFromRepository(); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GetSourceRepositoryDetailsFailed, error); - throw error; - } - } - - private async setWorkspace(): Promise { - const workspaceFolders = vscode.workspace && vscode.workspace.workspaceFolders; - if (workspaceFolders && workspaceFolders.length > 0) { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); - - if (workspaceFolders.length === 1) { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'false'); - this.workspacePath = workspaceFolders[0].uri.fsPath; - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.MultipleWorkspaceFolders, 'true'); - const workspaceFolderOptions: QuickPickItemWithData[] = []; - for (const folder of workspaceFolders) { - workspaceFolderOptions.push({ label: folder.name, data: folder }); - } - const selectedWorkspaceFolder = await this.controlProvider.showQuickPick( - constants.SelectFromMultipleWorkSpace, - workspaceFolderOptions, - { placeHolder: Messages.selectWorkspaceFolder }); - this.workspacePath = selectedWorkspaceFolder.data.uri.fsPath; - } - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.BrowseLocalMachine); - const selectedFolder: vscode.Uri[] = await vscode.window.showOpenDialog( - { - openLabel: Messages.selectFolderLabel, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - } - ); - if (selectedFolder && selectedFolder.length > 0) { - this.workspacePath = selectedFolder[0].fsPath; - } - else { - throw new UserCancelledError(Messages.noWorkSpaceSelectedError); - } - } - } - - private async getGitDetailsFromRepository(): Promise { - this.localGitRepoHelper = LocalGitRepoHelper.GetHelperInstance(this.workspacePath); - const isGitRepository = await this.localGitRepoHelper.isGitRepository(); - - if (isGitRepository) { - const gitBranchDetails = await this.localGitRepoHelper.getGitBranchDetails(); - - if (!gitBranchDetails.remoteName) { - // Remote tracking branch is not set - const remotes = await this.localGitRepoHelper.getGitRemotes(); - if (remotes.length === 0) { - this.setDefaultRepositoryDetails(); - } - else if (remotes.length === 1) { - gitBranchDetails.remoteName = remotes[0].name; - } - else { - // Show an option to user to select remote to be configured - const selectedRemote = await this.controlProvider.showQuickPick( - constants.SelectRemoteForRepo, - remotes.map((remote) => ({ label: remote.name })), - { placeHolder: Messages.selectRemoteForBranch }); - gitBranchDetails.remoteName = selectedRemote.label; - } - } - - // Set working directory relative to repository root - const gitRootDir = await this.localGitRepoHelper.getGitRootDirectory(); - this.inputs.pipelineConfiguration.workingDirectory = path.relative(gitRootDir, this.workspacePath).split(path.sep).join('/'); - - if (this.inputs.pipelineConfiguration.workingDirectory === "") { - this.inputs.pipelineConfiguration.workingDirectory = "."; - } - - this.inputs.sourceRepository = this.inputs.sourceRepository ? this.inputs.sourceRepository : await this.getGitRepositoryParameters(gitBranchDetails); - } - else { - this.setDefaultRepositoryDetails(); - } - // set telemetry - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, this.inputs.sourceRepository.repositoryProvider); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, this.inputs.sourceRepository.repositoryId); - } - - private setDefaultRepositoryDetails(): void { - extensionVariables.isLocalRepo = true; - this.inputs.pipelineConfiguration.workingDirectory = '.'; - this.inputs.sourceRepository = { - branch: 'master', - commitId: '', - localPath: this.workspacePath, - remoteName: 'origin', - remoteUrl: '', - repositoryId: '', - repositoryName: '', - repositoryProvider: vscode.workspace.getConfiguration().get('deployToAzure.UseGithubForCreatingNewRepository') ? RepositoryProvider.Github : RepositoryProvider.AzureRepos, - }; - } - - private async getGitRepositoryParameters(gitRepositoryDetails: GitBranchDetails): Promise { - const remoteUrl = await this.localGitRepoHelper.getGitRemoteUrl(gitRepositoryDetails.remoteName); - - if (remoteUrl) { - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - return { - repositoryProvider: RepositoryProvider.AzureRepos, - repositoryId: "", - repositoryName: AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl).repositoryName, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - const repoId = GitHubProvider.getRepositoryIdFromUrl(remoteUrl); - return { - repositoryProvider: RepositoryProvider.Github, - repositoryId: repoId, - repositoryName: repoId, - remoteName: gitRepositoryDetails.remoteName, - remoteUrl, - branch: gitRepositoryDetails.branch, - commitId: "", - localPath: this.workspacePath - }; - } - else { - let repositoryProvider: string; - - if (remoteUrl.indexOf("bitbucket.org") >= 0) { - repositoryProvider = "Bitbucket"; - } - else if (remoteUrl.indexOf("gitlab.com") >= 0) { - repositoryProvider = "GitLab"; - } - else { - repositoryProvider = remoteUrl; - } - - telemetryHelper.setTelemetry(TelemetryKeys.RepoProvider, repositoryProvider); - throw new WhiteListedError(Messages.cannotIdentifyRespositoryDetails); - } - } - else { - throw new Error(Messages.remoteRepositoryNotConfigured); - } - } - - private async extractAzureResourceFromNode(node: IResourceNode): Promise { - if (!!node.resource.id && node.resource.type != 'cluster') { - this.inputs.subscriptionId = node.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId); - - try { - const azureResource: GenericResource = await (this.azureResourceClient as AppServiceClient).getAppServiceResource(node.resource.id); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, azureResource.type); - telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, azureResource.kind); - AzureResourceClient.validateTargetResourceType(azureResource); - if (azureResource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - if (await (this.azureResourceClient as AppServiceClient).isScmTypeSet(node.resource.id)) { - this.continueOrchestration = false; - await openBrowseExperience(node.resource.id); - } - } - - this.inputs.targetResource.resource = azureResource; - return true; - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ExtractAzureResourceFromNodeFailed, error); - throw error; - } - } - else if (!!node.resource.id && node.resource.type === "cluster") { - this.inputs.subscriptionId = node.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - this.azureResourceClient = new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId); - const cluster = await this.azureResourceClient.getResource(node.resource.id, '2019-08-01'); - telemetryHelper.setTelemetry(TelemetryKeys.resourceType, cluster.type); - AzureResourceClient.validateTargetResourceType(cluster); - cluster["parsedResourceId"] = new ParsedAzureResourceId(cluster.id); - this.inputs.targetResource.resource = cluster; - return true; - } - return false; - } - - private async getAzureSubscription(): Promise { - // show available subscriptions and get the chosen one - const subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - const selectedSubscription: QuickPickItemWithData = await this.controlProvider.showQuickPick(constants.SelectSubscription, subscriptionList, { placeHolder: Messages.selectSubscription }, TelemetryKeys.SubscriptionListCount); - this.inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - this.context['subscriptionId'] = this.inputs.subscriptionId; - this.inputs.azureSession = await getSubscriptionSession(this.inputs.subscriptionId); - telemetryHelper.setTelemetry(TelemetryKeys.SubscriptionId, this.inputs.subscriptionId); - } - - private async getTemplatesByRepoAnalysis(repoAnalysisResult: RepositoryAnalysis): Promise { - - let appropriatePipelines: PipelineTemplate[] = []; - const remotePipelines: PipelineTemplate[] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.fetchingTemplates }, - () => templateHelper.analyzeRepoAndListAppropriatePipeline2( - this.inputs.azureSession, - this.inputs.sourceRepository, - this.pipelineType, - repoAnalysisResult, - this.inputs.githubPATToken, - this.inputs.targetResource.resource) - ); - appropriatePipelines = remotePipelines; - - const pipelineMap = this.getMapOfUniqueLabels(appropriatePipelines); - const pipelineLabels = Array.from(pipelineMap.keys()); - if (pipelineLabels.length === 0) { - telemetryHelper.setTelemetry(TelemetryKeys.UnsupportedLanguage, Messages.languageNotSupported); - throw new Error(Messages.languageNotSupported); - } - - if (pipelineLabels.length > 1) { - const selectedOption = await this.controlProvider.showQuickPick( - constants.SelectPipelineTemplate, - pipelineLabels.map((pipeline) => ({ label: pipeline })), - { placeHolder: Messages.selectPipelineTemplate }, - TelemetryKeys.PipelineTempateListCount); - // only label gets finalized, template isn't final yet - this.inputs.potentialTemplates = pipelineMap.get(selectedOption.label); - } - else { - this.inputs.potentialTemplates = pipelineMap.get(pipelineLabels[0]); - } - } - - private getMapOfUniqueLabels(pipelines: PipelineTemplate[]): Map { - const pipelineMap: Map = new Map(); - if (!!pipelines) { - pipelines.forEach((element) => { - if (pipelineMap.has(element.label)) { - pipelineMap.get(element.label).push(element); - } - else { - pipelineMap.set(element.label, [element]); - } - }); - } - return pipelineMap; - } - - private async updateRepositoryAnalysisApplicationSettings(repoAnalysisResult: RepositoryAnalysis): Promise { - // If RepoAnalysis is disabled or didn't provided response related to language of selected template - this.inputs.repositoryAnalysisApplicationSettings = {} as ApplicationSettings; - - if (!repoAnalysisResult || !repoAnalysisResult.applicationSettingsList) { - return; - } - - let applicationSettings: ApplicationSettings[] = repoAnalysisResult.applicationSettingsList; - if (!this.isResourceAlreadySelected()) { - const workingDirectories = Array.from(new Set(this.inputs.potentialTemplates - .filter((template) => template.templateType === TemplateType.REMOTE) - .map((template: RemotePipelineTemplate) => template.workingDirectory.toLowerCase()))); - applicationSettings = repoAnalysisResult.applicationSettingsList.filter((applicationSetting) => { - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return workingDirectories.indexOf(applicationSetting.settings.workingDirectory.toLowerCase()) >= 0; - } - return applicationSetting.language === this.inputs.pipelineConfiguration.template.language; - - }); - } - this.context['repoAnalysisSettings'] = applicationSettings; - - if (!applicationSettings || applicationSettings.length === 0 || - this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - return; - } - - if (applicationSettings.length === 1) { - this.inputs.repositoryAnalysisApplicationSettings = applicationSettings[0]; - this.inputs.pipelineConfiguration.workingDirectory = applicationSettings[0].settings.workingDirectory; - return; - } - - const workspacePaths = Array.from(new Set(applicationSettings.map((a) => a.settings.workingDirectory))); - const workspacePathQuickPickItemList: QuickPickItemWithData[] = []; - for (const workspacePath of workspacePaths) { - workspacePathQuickPickItemList.push({ label: workspacePath, data: workspacePath }); - } - const selectedWorkspacePathItem = await this.controlProvider.showQuickPick( - constants.SelectWorkspace, - workspacePathQuickPickItemList, - { placeHolder: Messages.selectWorkspace }); - - this.inputs.pipelineConfiguration.workingDirectory = selectedWorkspacePathItem.data; - this.inputs.repositoryAnalysisApplicationSettings = - repoAnalysisResult.applicationSettingsList.find((applicationSettings) => { - return (applicationSettings.language === this.inputs.pipelineConfiguration.template.language - && applicationSettings.settings.workingDirectory === selectedWorkspacePathItem.data); - }); - } - - private async checkInPipelineFileToRepository(pipelineConfigurer: Configurer): Promise { - let filesToCommit: string[] = []; - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE) { - filesToCommit = await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).getPipelineFilesToCommit(this.inputs); - } - else { - try { - const mustacheContext = new MustacheContext(this.inputs); - if (this.inputs.pipelineConfiguration.template.targetType === TargetResourceType.AKS) { - try { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.deploymentManifest, pipelineConfigurer, filesToCommit, this.inputs); - const properties = this.inputs.pipelineConfiguration.params.aksCluster.properties; - if (properties.addonProfiles && properties.addonProfiles.httpApplicationRouting && properties.addonProfiles.httpApplicationRouting.enabled) { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceIngressManifest, pipelineConfigurer, filesToCommit, this.inputs, constants.serviceManifest); - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.ingressManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - else { - await this.localGitRepoHelper.createAndDisplayManifestFile(constants.serviceManifest, pipelineConfigurer, filesToCommit, this.inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreatingManifestsFailed, error); - throw error; - } - } - - this.inputs.pipelineConfiguration.filePath = await pipelineConfigurer.getPathToPipelineFile(this.inputs, this.localGitRepoHelper); - filesToCommit.push(this.inputs.pipelineConfiguration.filePath); - await this.localGitRepoHelper.addContentToFile( - await templateHelper.renderContent((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).path, mustacheContext), - this.inputs.pipelineConfiguration.filePath); - await vscode.window.showTextDocument(vscode.Uri.file(this.inputs.pipelineConfiguration.filePath)); - telemetryHelper.setTelemetry(TelemetryKeys.DisplayWorkflow, 'true'); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AddingContentToPipelineFileFailed, error); - throw error; - } - } - - try { - await pipelineConfigurer.checkInPipelineFilesToRepository(filesToCommit, this.inputs, this.localGitRepoHelper); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PipelineFileCheckInFailed, error); - throw error; - } - } - - private createProvisioningConfigurationObject(templateId: string, branch: string, pipeplineTemplateParameters: { [key: string]: string }, mode: provisioningMode): ProvisioningConfiguration { - return { - id: null, - branch, - pipelineTemplateId: templateId, - pipelineTemplateParameters: pipeplineTemplateParameters, - provisioningMode: mode, - } as ProvisioningConfiguration; - } - - private async configurePipelineRemotely(): Promise { - const provisioningConfigurer = new ProvisioningConfigurer(this.localGitRepoHelper); - const template = this.inputs.pipelineConfiguration.template as RemotePipelineTemplate; - try { - // prerequisite params - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParams'); - await provisioningConfigurer.createPreRequisiteParams(this.inputs); - - // Draft pipeline step - telemetryHelper.setCurrentStep('ConfiguringDraftProvisioningPipeline'); - const provisioningConfiguration = this.createProvisioningConfigurationObject(template.id, this.inputs.sourceRepository.branch, this.inputs.pipelineConfiguration.params, provisioningMode.draft); - const draftProvisioningPipeline: ProvisioningConfiguration = await provisioningConfigurer.preSteps(provisioningConfiguration, this.inputs); - - // After recieving the draft workflow files, show them to user and confirm to checkin - telemetryHelper.setCurrentStep('ConfiguringCompleteProvisioningPipeline'); - provisioningConfiguration.provisioningMode = provisioningMode.complete; - await provisioningConfigurer.postSteps(provisioningConfiguration, (draftProvisioningPipeline.result.pipelineConfiguration as DraftPipelineConfiguration), this.inputs); - - // All done, now browse the pipeline - telemetryHelper.setCurrentStep('BrowsingPipeline'); - await provisioningConfigurer.browseQueuedWorkflow(); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - throw error; - } - } - - private async ConfigurePipelineLocally() { - const pipelineConfigurer = ConfigurerFactory.GetConfigurer(this.inputs.sourceRepository, this.inputs.azureSession, - this.inputs.pipelineConfiguration.template.templateType, this.localGitRepoHelper); - const selectedCICDProvider = (pipelineConfigurer.constructor.name === "AzurePipelineConfigurer") ? constants.azurePipeline : constants.githubWorkflow; - telemetryHelper.setTelemetry(TelemetryKeys.SelectedCICDProvider, selectedCICDProvider); - await pipelineConfigurer.getInputs(this.inputs); - telemetryHelper.setCurrentStep('CreatePreRequisites'); - await pipelineConfigurer.createPreRequisites(this.inputs, !!this.azureResourceClient ? this.azureResourceClient : new AppServiceClient(this.inputs.azureSession.credentials, this.inputs.azureSession.environment, this.inputs.azureSession.tenantId, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('CreateAssets'); - if (this.inputs.pipelineConfiguration.template.templateType === TemplateType.REMOTE && this.inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - await (pipelineConfigurer as RemoteGitHubWorkflowConfigurer).createAssets(ConfigurationStage.Pre); - } else { - await new AssetHandler().createAssets((this.inputs.pipelineConfiguration.template as LocalPipelineTemplate).assets, this.inputs, (name: string, assetType: TemplateAssetType, data: any, inputs: WizardInputs) => pipelineConfigurer.createAsset(name, assetType, data, inputs)); - } - - telemetryHelper.setCurrentStep('CheckInPipeline'); - await this.checkInPipelineFileToRepository(pipelineConfigurer); - - telemetryHelper.setCurrentStep('CreateAndRunPipeline'); - await pipelineConfigurer.createAndQueuePipeline(this.inputs); - - telemetryHelper.setCurrentStep('PostPipelineCreation'); - // This step should be determined by the resoruce target provider (azure app service, function app, aks) type and pipelineProvider(azure pipeline vs github) - pipelineConfigurer.executePostPipelineCreationSteps(this.inputs, this.azureResourceClient ? this.azureResourceClient : new AzureResourceClient(this.inputs.azureSession.credentials, this.inputs.subscriptionId)); - - telemetryHelper.setCurrentStep('DisplayCreatedPipeline'); - pipelineConfigurer.browseQueuedPipeline(); - } - - private initializeClientFactories(): void { - TemplateServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - ProvisioningServiceClientFactory.initialize(this.inputs.azureSession.credentials, this.inputs.githubPATToken); - } -} - -export async function openBrowseExperience(resourceId: string): Promise { - try { - // if pipeline is already setup, the ask the user if we should continue. - telemetryHelper.setTelemetry(TelemetryKeys.PipelineAlreadyConfigured, 'true'); - - const browsePipelineAction = await new ControlProvider().showInformationBox( - constants.SetupAlreadyExists, - Messages.setupAlreadyConfigured, - constants.Browse); - - if (browsePipelineAction === constants.Browse) { - vscode.commands.executeCommand('browse-cicd-pipeline', { fullId: resourceId }); - } - } - catch (err) { - if (!(err instanceof UserCancelledError)) { - throw err; - } - } - - telemetryHelper.setResult(Result.Succeeded); -} diff --git a/src/configure/configurers/AksAzureResourceSelector.ts b/src/configure/configurers/AksAzureResourceSelector.ts deleted file mode 100644 index ffdf9e32..00000000 --- a/src/configure/configurers/AksAzureResourceSelector.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { TargetResourceType } from "../model/models"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class AksAzureResourceSelector implements IAzureResourceSelector { - async getAzureResource(inputs): Promise { - return { type: TargetResourceType.AKS }; - - } - -} - diff --git a/src/configure/configurers/IAzureResourceSelector.ts b/src/configure/configurers/IAzureResourceSelector.ts deleted file mode 100644 index 0e697bfd..00000000 --- a/src/configure/configurers/IAzureResourceSelector.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; - -export interface IAzureResourceSelector { - getAzureResource(inputs): Promise; -} - diff --git a/src/configure/configurers/IProvisioningConfigurer.ts b/src/configure/configurers/IProvisioningConfigurer.ts deleted file mode 100644 index 06a676d2..00000000 --- a/src/configure/configurers/IProvisioningConfigurer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { WizardInputs } from '../model/models'; -import { DraftPipelineConfiguration, ProvisioningConfiguration } from '../model/provisioningConfiguration'; - -export interface IProvisioningConfigurer { - queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise; - getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise; - postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise; - preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise; - browseQueuedWorkflow(): Promise; -} diff --git a/src/configure/configurers/ResourceSelectorFactory.ts b/src/configure/configurers/ResourceSelectorFactory.ts deleted file mode 100644 index cd4b5f32..00000000 --- a/src/configure/configurers/ResourceSelectorFactory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ServiceClientCredentials } from "ms-rest"; -import { AzureEnvironment } from "ms-rest-azure"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { TargetResourceType } from "../model/models"; -import { Messages } from "../resources/messages"; -import { AksAzureResourceSelector } from "./AksAzureResourceSelector"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; -import { WebAppAzureResourceSelector } from "./WebAppAzureResourceSelector"; - -export class ResourceSelectorFactory { - - public static getAzureResourceSelector(targetType: TargetResourceType): IAzureResourceSelector { - switch (targetType) { - case TargetResourceType.WebApp: - return new WebAppAzureResourceSelector(); - case TargetResourceType.AKS: - return new AksAzureResourceSelector(); - default: - throw new Error(Messages.ResourceNotSupported); - } - } - - public static getAzureResourceClient(targetType: TargetResourceType, credentials: ServiceClientCredentials, environment: AzureEnvironment, tenantId: string, subscriptionId: string): AzureResourceClient { - switch (targetType) { - case TargetResourceType.WebApp: - return new AppServiceClient(credentials, environment, tenantId, subscriptionId); - case TargetResourceType.AKS: - return new AzureResourceClient(credentials, subscriptionId); - default: - throw new Error(Messages.ResourceNotSupported); - } - } -} \ No newline at end of file diff --git a/src/configure/configurers/WebAppAzureResourceSelector.ts b/src/configure/configurers/WebAppAzureResourceSelector.ts deleted file mode 100644 index fc4de851..00000000 --- a/src/configure/configurers/WebAppAzureResourceSelector.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { openBrowseExperience } from "../configure"; -import { ControlProvider } from "../helper/controlProvider"; -import { QuickPickItemWithData, WizardInputs } from "../model/models"; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { IAzureResourceSelector } from "./IAzureResourceSelector"; - -export class WebAppAzureResourceSelector implements IAzureResourceSelector { - - async getAzureResource(inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = inputs.potentialTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw new Error(Messages.setupAlreadyConfigured); - } - return selectedResource.data; - } - -} - diff --git a/src/configure/configurers/azurePipelineConfigurer.ts b/src/configure/configurers/azurePipelineConfigurer.ts deleted file mode 100644 index 692e591d..00000000 --- a/src/configure/configurers/azurePipelineConfigurer.ts +++ /dev/null @@ -1,390 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, VSTSDeploymentMessage } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { AzureDevOpsClient } from "../clients/devOps/azureDevOpsClient"; -import { UniqueResourceNameSuffix } from '../configure'; -import { generateDevOpsOrganizationName, generateDevOpsProjectName } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { AzureDevOpsHelper } from "../helper/devOps/azureDevOpsHelper"; -import { ServiceConnectionHelper } from '../helper/devOps/serviceConnectionHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { Build } from '../model/azureDevOps'; -import { AzureConnectionType, AzureSession, RepositoryProvider, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { WhiteListedError } from '../utilities/utilities'; -import { Configurer } from "./configurerBase"; -import Q = require('q'); - -const Layer = 'AzurePipelineConfigurer'; - -export class AzurePipelineConfigurer implements Configurer { - private azureDevOpsHelper: AzureDevOpsHelper; - private azureDevOpsClient: AzureDevOpsClient; - private queuedPipeline: Build; - private controlProvider: ControlProvider; - - constructor(azureSession: AzureSession) { - this.azureDevOpsClient = new AzureDevOpsClient(azureSession.credentials); - this.azureDevOpsHelper = new AzureDevOpsHelper(this.azureDevOpsClient); - this.controlProvider = new ControlProvider(); - this.azureDevOpsClient.listOrganizations(true); - } - - public async getInputs(inputs: WizardInputs): Promise { - try { - inputs.isNewOrganization = false; - - if (!inputs.sourceRepository.remoteUrl || inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - let devOpsOrganizations = await this.azureDevOpsClient.listOrganizations(); - - if (devOpsOrganizations && devOpsOrganizations.length > 0) { - let selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectOrganization, - devOpsOrganizations.map(x => { return { label: x.accountName }; }), - { placeHolder: Messages.selectOrganization }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - - let selectedProject = await this.controlProvider.showQuickPick( - constants.SelectProject, - this.azureDevOpsClient.listProjects(inputs.organizationName) - .then((projects) => projects.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectProject }, - TelemetryKeys.ProjectListCount); - inputs.project = selectedProject.data; - } - else { - inputs.isNewOrganization = true; - let userName = inputs.azureSession.userId.substring(0, inputs.azureSession.userId.indexOf("@")); - let organizationName = generateDevOpsOrganizationName(userName, inputs.sourceRepository.repositoryName); - - let validationErrorMessage = await this.azureDevOpsClient.validateOrganizationName(organizationName); - if (validationErrorMessage) { - inputs.organizationName = await this.controlProvider.showInputBox( - constants.EnterOrganizationName, - { - placeHolder: Messages.enterAzureDevOpsOrganizationName, - validateInput: (organizationName) => this.azureDevOpsClient.validateOrganizationName(organizationName) - }); - } - else { - inputs.organizationName = organizationName; - } - inputs.project = { - id: "", - name: generateDevOpsProjectName(inputs.sourceRepository.repositoryName) - }; - } - } - else { - let repoDetails = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(inputs.sourceRepository.remoteUrl); - inputs.organizationName = repoDetails.organizationName; - await this.azureDevOpsClient.getRepository(inputs.organizationName, repoDetails.projectName, inputs.sourceRepository.repositoryName) - .then((repository) => { - inputs.sourceRepository.repositoryId = repository.id; - inputs.project = { - id: repository.project.id, - name: repository.project.name - }; - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - }); - } - - telemetryHelper.setTelemetry(TelemetryKeys.NewOrganization, inputs.isNewOrganization.toString()); - } - catch (error) { - if ((error.typeKey as string).toUpperCase() === constants.ExceptionType.UnauthorizedRequestException) { - throw new WhiteListedError((error.message as string).concat(Messages.AdoDifferentTenantError), error); - } - telemetryHelper.logError(Layer, TracePoints.GetAzureDevOpsDetailsFailed, error); - throw error; - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.isNewOrganization) { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingAzureDevOpsOrganization - }, - async () => { - try { - // Create DevOps organization - await this.azureDevOpsClient.createOrganization(inputs.organizationName); - this.azureDevOpsClient.listOrganizations(true); - - // Create DevOps project - await this.azureDevOpsClient.createProject(inputs.organizationName, inputs.project.name); - inputs.project.id = await this.azureDevOpsClient.getProjectIdFromName(inputs.organizationName, inputs.project.name); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateNewOrganizationAndProjectFailure, error); - throw error; - } - }); - } - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - // Create GitHub service connection in Azure DevOps - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.creatingGitHubServiceConnection - }, - async () => { - try { - let serviceConnectionName = `${inputs.sourceRepository.repositoryName}-${UniqueResourceNameSuffix}`; - inputs.sourceRepository.serviceConnectionId = await serviceConnectionHelper.createGitHubServiceConnection(serviceConnectionName, inputs.githubPATToken); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.GitHubServiceConnectionError, error); - throw error; - } - }); - } - - if (!!inputs.targetResource.resource) { - // TODO: show notification while setup is being done. - // ?? should SPN created be scoped to resource group of target azure resource. - inputs.targetResource.serviceConnectionId = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - let serviceConnectionName = `${inputs.targetResource.resource.name}-${UniqueResourceNameSuffix}`; - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return ''; - case AzureConnectionType.AzureRMPublishProfile: - return await this.createAzurePublishProfileEndpoint(serviceConnectionHelper, azureResourceClient, serviceConnectionName, inputs); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.createAzureSPNServiceEndpoint(serviceConnectionHelper, serviceConnectionName, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let serviceConnectionHelper = new ServiceConnectionHelper(inputs.organizationName, inputs.project.name, this.azureDevOpsClient); - - switch (type) { - case TemplateAssetType.AzureARMServiceConnection: - return await serviceConnectionHelper.createAzureSPNServiceConnection(name, inputs.azureSession.tenantId, inputs.subscriptionId, data.scope, data.aadApp); - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebApp = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(name, inputs.azureSession.tenantId, targetWebApp.id, data); - case TemplateAssetType.AKSKubeConfigServiceConnection: - let targetAks = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - let serverUrl = targetAks.properties ? targetAks.properties.fqdn : ''; - serverUrl = !!serverUrl && !serverUrl.startsWith('https://') ? 'https://' + serverUrl : serverUrl; - return await serviceConnectionHelper.createKubeConfigServiceConnection(name, data, serverUrl); - case TemplateAssetType.ACRServiceConnection: - let targetAcr = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - let registryUrl: string = targetAcr.properties ? targetAcr.properties.loginServer : ''; - registryUrl = !!registryUrl && !registryUrl.startsWith('https://') ? 'https://' + registryUrl : registryUrl; - let password = !!data.passwords && data.passwords.length > 0 ? data.passwords[0].value : null; - return await serviceConnectionHelper.createContainerRegistryServiceConnection(name, registryUrl, data.username, password); - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForAzurePipelines, type)); - } - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - let rootDirectory = await localGitRepoHelper.getGitRootDirectory(); - return path.join(rootDirectory, await LocalGitRepoHelper.GetAvailableFileName('azure-pipelines.yml', rootDirectory)); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { return null; } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - let commitMessage: string; - let initializeGitRepository = !inputs.sourceRepository.remoteUrl; - - if (!inputs.sourceRepository.remoteUrl) { - commitMessage = Messages.modifyAndCommitFileWithGitInitialization; - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'true'); - } - else { - commitMessage = utils.format(Messages.modifyAndCommitFile, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName); - telemetryHelper.setTelemetry(TelemetryKeys.NewDevOpsRepository, 'false'); - } - - while (!inputs.sourceRepository.commitId) { - let commitOrDiscard = await vscode.window.showInformationMessage( - commitMessage, - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - if (!inputs.sourceRepository.remoteUrl) { - let repositoryName = path.basename(inputs.sourceRepository.localPath).trim().replace(/[^a-zA-Z0-9-]/g, ''); - repositoryName = !!repositoryName ? (repositoryName + UniqueResourceNameSuffix) : "codetoazure"; - let repository = await this.azureDevOpsClient.createRepository(inputs.organizationName, inputs.project.id, repositoryName); - inputs.sourceRepository.repositoryName = repository.name; - inputs.sourceRepository.repositoryId = repository.id; - inputs.sourceRepository.remoteUrl = repository.remoteUrl; - } - - if (initializeGitRepository) { - await localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl, inputs.pipelineConfiguration.filePath); - - let branchDetails = await localGitRepoHelper.getGitBranchDetails(); - inputs.sourceRepository.branch = branchDetails.branch; - initializeGitRepository = false; - } - - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipeline = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - let targetResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let pipelineName = `${(targetResource ? targetResource.name : inputs.pipelineConfiguration.template.label)}-${UniqueResourceNameSuffix}`; - return await this.azureDevOpsHelper.createAndRunPipeline(pipelineName, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CreateAndQueuePipelineFailed, error); - throw error; - } - }); - - return this.queuedPipeline._links.web.href; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.pipelineConfiguration.template.targetType === TargetResourceType.WebApp) { - try { - // update SCM type - let targetResource: GenericResource = AzurePipelineConfigurer.getTargetResource(inputs); - - let updateScmPromise = (azureResourceClient as AppServiceClient).updateScmType(targetResource.id); - - let buildDefinitionUrl = this.azureDevOpsClient.getOldFormatBuildDefinitionUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.definition.id); - let buildUrl = this.azureDevOpsClient.getOldFormatBuildUrl(inputs.organizationName, inputs.project.id, this.queuedPipeline.id); - - // update metadata of app service to store information about the pipeline deploying to web app. - let updateMetadataPromise = new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(targetResource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - metadata["properties"]["VSTSRM_ProjectId"] = `${inputs.project.id}`; - metadata["properties"]["VSTSRM_AccountId"] = await this.azureDevOpsClient.getOrganizationIdFromName(inputs.organizationName); - metadata["properties"]["VSTSRM_BuildDefinitionId"] = `${this.queuedPipeline.definition.id}`; - metadata["properties"]["VSTSRM_BuildDefinitionWebAccessUrl"] = `${buildDefinitionUrl}`; - metadata["properties"]["VSTSRM_ConfiguredCDEndPoint"] = ''; - metadata["properties"]["VSTSRM_ReleaseDefinitionId"] = ''; - - (azureResourceClient as AppServiceClient).updateAppServiceMetadata(targetResource.id, metadata); - resolve(); - }); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage, - VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`, - VSTSRM_ConfiguredCDEndPoint: '', - VSTSRM_BuildWebAccessUrl: `${buildUrl}`, - }); - - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService( - targetResource.id, deploymentMessage); - - Q.all([updateScmPromise, updateMetadataPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.pipelineSetupSuccessfully, Messages.browsePipeline) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browsePipeline.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipeline._links.web.href)); - } - }); - } - - private static getTargetResource(inputs: WizardInputs): GenericResource { - let targetResource = !!inputs.targetResource.resource ? inputs.targetResource.resource : null; - if (!targetResource) { - let targetParam = TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, inputs.pipelineConfiguration.template.targetType); - if (!!targetParam && !!inputs.pipelineConfiguration.params[targetParam.name]) { - targetResource = inputs.pipelineConfiguration.params[targetParam.name]; - } - else { - throw new Error(utils.format(Messages.couldNotFindTargetResourceValueInParams, inputs.pipelineConfiguration.template.targetType)); - } - } - - return targetResource; - } - - private async createAzurePublishProfileEndpoint(serviceConnectionHelper: ServiceConnectionHelper, azureResourceClient: AzureResourceClient, serviceConnectionName: string, inputs: WizardInputs): Promise { - let publishProfile = await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - return await serviceConnectionHelper.createAzurePublishProfileServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.targetResource.resource.id, publishProfile); - } - - private async createAzureSPNServiceEndpoint(serviceConnectionHelper: ServiceConnectionHelper, serviceConnectionName: string, inputs: WizardInputs): Promise { - let scope = inputs.targetResource.resource.id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return await serviceConnectionHelper.createAzureSPNServiceConnection(serviceConnectionName, inputs.azureSession.tenantId, inputs.subscriptionId, scope, aadApp); - } -} diff --git a/src/configure/configurers/configurerBase.ts b/src/configure/configurers/configurerBase.ts deleted file mode 100644 index db858f3d..00000000 --- a/src/configure/configurers/configurerBase.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { LocalGitRepoHelper } from "../helper/LocalGitRepoHelper"; -import { WizardInputs } from "../model/models"; -import { TemplateAssetType } from "../model/templateModels"; - -export interface Configurer { - validatePermissions(): Promise; - getInputs(inputs: WizardInputs): Promise; - createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise; - getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise; - checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise; - createAndQueuePipeline(inputs: WizardInputs): Promise; - executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise; - browseQueuedPipeline(): Promise; -} diff --git a/src/configure/configurers/configurerFactory.ts b/src/configure/configurers/configurerFactory.ts deleted file mode 100644 index d6e61011..00000000 --- a/src/configure/configurers/configurerFactory.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { AzureSession, extensionVariables, GitRepositoryParameters, RepositoryProvider } from '../model/models'; -import { TemplateType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { AzurePipelineConfigurer } from './azurePipelineConfigurer'; -import { Configurer } from './configurerBase'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; -import { RemoteGitHubWorkflowConfigurer } from './remoteGitHubWorkflowConfigurer'; - -export class ConfigurerFactory { - public static GetConfigurer(sourceRepositoryDetails: GitRepositoryParameters, azureSession: AzureSession, templateType: TemplateType, localGitRepoHelper: LocalGitRepoHelper): Configurer { - switch (sourceRepositoryDetails.repositoryProvider) { - case RepositoryProvider.Github: - if (extensionVariables.enableGitHubWorkflow) { - return templateType === TemplateType.LOCAL ? new LocalGitHubWorkflowConfigurer(localGitRepoHelper) : new RemoteGitHubWorkflowConfigurer(azureSession, localGitRepoHelper); - } - return new AzurePipelineConfigurer(azureSession); - case RepositoryProvider.AzureRepos: - return new AzurePipelineConfigurer(azureSession); - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - } -} diff --git a/src/configure/configurers/localGithubWorkflowConfigurer.ts b/src/configure/configurers/localGithubWorkflowConfigurer.ts deleted file mode 100644 index 89da8d49..00000000 --- a/src/configure/configurers/localGithubWorkflowConfigurer.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import * as fs from 'fs'; -import * as ymlconfig from 'js-yaml'; -import * as path from 'path'; -import * as Q from 'q'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { AppServiceClient, DeploymentMessage } from '../clients/azure/appServiceClient'; -import { ApiVersions, AzureResourceClient } from '../clients/azure/azureResourceClient'; -import { GithubClient } from '../clients/github/githubClient'; -import { generateGitHubRepository } from "../helper/commonHelper"; -import { ControlProvider } from '../helper/controlProvider'; -import { GitHubProvider } from '../helper/gitHubHelper'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { TemplateParameterHelper } from '../helper/templateParameterHelper'; -import { AzureConnectionType, extensionVariables, GitHubRepo, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAssetType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { Configurer } from "./configurerBase"; - - -const uuid = require('uuid/v4'); -const Layer = 'LocalGitHubWorkflowConfigurer'; - -export class LocalGitHubWorkflowConfigurer implements Configurer { - protected githubClient: GithubClient; - private queuedPipelineUrl: string; - private controlProvider: ControlProvider; - private localGitRepoHelper: LocalGitRepoHelper; - - constructor(localgitRepoHelper: LocalGitRepoHelper) { - this.controlProvider = new ControlProvider(); - this.localGitRepoHelper = localgitRepoHelper; - } - - public async getInputs(inputs: WizardInputs): Promise { - this.githubClient = new GithubClient(inputs.githubPATToken, inputs.sourceRepository.remoteUrl); - inputs.isNewOrganization = false; - if (!inputs.sourceRepository.remoteUrl) { - const githubOrganizations = await this.githubClient.listOrganizations(); - - if (githubOrganizations && githubOrganizations.length > 0) { - const selectedOrganization = await this.controlProvider.showQuickPick( - constants.SelectGitHubOrganization, - githubOrganizations.map(x => { return { label: x.login }; }), - { placeHolder: Messages.selectGitHubOrganizationName }, - TelemetryKeys.OrganizationListCount); - inputs.organizationName = selectedOrganization.label; - const isUserAccount = githubOrganizations.find((x) => x.login === selectedOrganization.label).isUserAccount; - - try { - const newGitHubRepo = await generateGitHubRepository(inputs.organizationName, inputs.sourceRepository.localPath, this.githubClient, isUserAccount) as GitHubRepo; - this.githubClient.setRepoUrl(newGitHubRepo.html_url); - inputs.sourceRepository.remoteName = newGitHubRepo.name; - inputs.sourceRepository.remoteUrl = newGitHubRepo.html_url + ".git"; - inputs.sourceRepository.repositoryId = GitHubProvider.getRepositoryIdFromUrl(inputs.sourceRepository.remoteUrl); - await this.localGitRepoHelper.initializeGitRepository(inputs.sourceRepository.remoteName, inputs.sourceRepository.remoteUrl); - telemetryHelper.setTelemetry(TelemetryKeys.RepoId, inputs.sourceRepository.repositoryId); - telemetryHelper.setTelemetry(TelemetryKeys.GitHubRepoCreated, 'true'); - vscode.window.showInformationMessage(utils.format(Messages.newGitHubRepositoryCreated, newGitHubRepo.name)); - } - catch (error) { - vscode.window.showErrorMessage(error.message); - throw error; - } - } - else { - vscode.window.showErrorMessage(Messages.createGitHubOrganization); - const error = new Error(Messages.createGitHubOrganization); - telemetryHelper.logError(Layer, TracePoints.NoGitHubOrganizationExists, error); - throw error; - } - } - } - - public async validatePermissions(): Promise { - return; - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type.toLowerCase() === TargetResourceType.WebApp.toLowerCase()) { - let azureConnectionSecret: string = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - switch ((inputs.pipelineConfiguration.template as LocalPipelineTemplate).azureConnectionType) { - case AzureConnectionType.None: - return null; - case AzureConnectionType.AzureRMPublishProfile: - return await (azureResourceClient as AppServiceClient).getWebAppPublishProfileXml(inputs.targetResource.resource.id); - case AzureConnectionType.AzureRMServicePrincipal: - default: - return await this.getAzureSPNSecret(inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - - if (!!azureConnectionSecret) { - inputs.targetResource.serviceConnectionId = 'AZURE_CREDENTIALS_' + uuid().substr(0, 8); - try { - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.createAsset(inputs.targetResource.serviceConnectionId, TemplateAssetType.GitHubARM, azureConnectionSecret, inputs); - }); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - } - } - } - - public async createAsset( - name: string, - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType, - data: any, - inputs: WizardInputs): Promise { - let secret: string = null; - switch (type) { - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubAKSKubeConfig: - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - secret = data; - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupportedForGitHub, type)); - } - - if (secret) { - await this.githubClient.createOrUpdateGithubSecret(name, secret); - } - - return name; - } - - public async getPathToPipelineFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, pipelineFileName?: string): Promise { - // Create .github directory - let workflowDirectoryPath = path.join('.github', 'workflows'); - if (!pipelineFileName) { - pipelineFileName = 'workflow.yml'; - } - return await this.getPathToFile(localGitRepoHelper, pipelineFileName, workflowDirectoryPath); - } - - public async getPathToManifestFile(inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper, fileName: string): Promise { - // Create manifests directory - let manifestsDirectoryPath: string = path.join(inputs.pipelineConfiguration.workingDirectory, 'manifests'); - try { - return await this.getPathToFile(localGitRepoHelper, fileName, manifestsDirectoryPath); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.ManifestsFolderCreationFailed, error); - throw error; - } - } - - public async getPathToFile(localGitRepoHelper: LocalGitRepoHelper, fileName: string, directory: string) { - let dirList = directory.split(path.sep); - let directoryPath: string = ""; - directoryPath = await localGitRepoHelper.getGitRootDirectory(); - dirList.forEach((dir) => { - try { - directoryPath = path.join(directoryPath, dir); - if (!fs.existsSync(directoryPath)) { - fs.mkdirSync(directoryPath); - } - } - catch (error) { - throw error; - } - }); - fileName = await LocalGitRepoHelper.GetAvailableFileName(fileName, directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return path.join(directoryPath, fileName); - } - - public async checkInPipelineFilesToRepository(filesToCommit: string[], inputs: WizardInputs, localGitRepoHelper: LocalGitRepoHelper): Promise { - - while (!inputs.sourceRepository.commitId) { - - let displayMessage = Messages.modifyAndCommitFile; - if (filesToCommit.length > 1) { - displayMessage = Messages.modifyAndCommitMultipleFiles; - } - - let commitOrDiscard = await vscode.window.showInformationMessage( - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - inputs.sourceRepository.commitId = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.configuringPipelineAndDeployment }, async () => { - try { - // handle when the branch is not upto date with remote branch and push fails - return await localGitRepoHelper.commitAndPushPipelineFile(filesToCommit, inputs.sourceRepository, extensionVariables.enableGitHubWorkflow ? Messages.addGitHubWorkflowYmlFile : Messages.addAzurePipelinesYmlFile); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CheckInPipelineFailure, error); - vscode.window.showErrorMessage(utils.format(Messages.commitFailedErrorMessage, error.message)); - return null; - } - }); - } - else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - throw new UserCancelledError(Messages.operationCancelled); - } - } - - return inputs.sourceRepository.commitId; - } - - public async createAndQueuePipeline(inputs: WizardInputs): Promise { - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${inputs.sourceRepository.commitId}/checks`; - return this.queuedPipelineUrl; - } - - public async executePostPipelineCreationSteps(inputs: WizardInputs, azureResourceClient: AzureResourceClient): Promise { - try { - if (inputs.targetResource && inputs.targetResource.resource && inputs.targetResource.resource.type === TargetResourceType.WebApp) { - // Update web app metadata - await new Promise(async (resolve) => { - let metadata = await (azureResourceClient as AppServiceClient).getAppServiceMetadata(inputs.targetResource.resource.id); - metadata["properties"] = metadata["properties"] ? metadata["properties"] : {}; - - let repositoryPath = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getGitRootDirectory(); - let configPath = path.relative(repositoryPath, inputs.pipelineConfiguration.filePath); - - const doc = ymlconfig.safeLoad(fs.readFileSync(inputs.pipelineConfiguration.filePath, 'utf8')); - if (!!doc["name"]) { - metadata["properties"]["configName"] = `${doc["name"]}`; - } - metadata["properties"]["configPath"] = `${configPath}`; - metadata["properties"]["repoUrl"] = `https://github.com/${inputs.sourceRepository.repositoryId}`; - metadata["properties"]["branch"] = inputs.sourceRepository.branch; - - await (azureResourceClient as AppServiceClient).updateAppServiceMetadata(inputs.targetResource.resource.id, metadata); - resolve(); - }); - - // Update web app sourceControls as GitHubAction - const sourceControlProperties = { - "isGitHubAction": true, - "repoUrl": `https://github.com/${inputs.sourceRepository.repositoryId}`, - "branch": inputs.sourceRepository.branch, - }; - let sourceControlPromise = (azureResourceClient as AppServiceClient).setSourceControl(inputs.targetResource.resource.id, sourceControlProperties); - - // send a deployment log with information about the setup pipeline and links. - let deploymentMessage = JSON.stringify({ - type: constants.DeploymentMessageType, - message: Messages.deploymentLogMessage - }); - - let authorName = await LocalGitRepoHelper.GetHelperInstance(inputs.sourceRepository.localPath).getUsername(); - let deployerName = 'GITHUBACTION'; - let updateDeploymentLogPromise = (azureResourceClient as AppServiceClient).publishDeploymentToAppService(inputs.targetResource.resource.id, deploymentMessage, authorName, deployerName); - Q.all([sourceControlPromise, updateDeploymentLogPromise]) - .then(() => { - telemetryHelper.setTelemetry(TelemetryKeys.UpdatedWebAppMetadata, 'true'); - }); - } - else if (TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS)) { - let aksResource: GenericResource = inputs.pipelineConfiguration.params[TemplateParameterHelper.getParameterForTargetResourceType((inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters, TargetResourceType.AKS).name]; - let workflowFileName = path.basename(inputs.pipelineConfiguration.filePath); - await azureResourceClient.updateCdSetupResourceTag(aksResource, inputs.sourceRepository.repositoryId, inputs.sourceRepository.branch, workflowFileName, inputs.sourceRepository.commitId, inputs.pipelineConfiguration.params['namespace'], ApiVersions.get(TargetResourceType.AKS)); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.PostDeploymentActionFailed, error); - } - } - - public async browseQueuedPipeline(): Promise { - vscode.window.showInformationMessage(Messages.githubWorkflowSetupSuccessfully, Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - protected async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - scope = !scope ? inputs.targetResource.resource.id : scope; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - "clientId": `${aadApp.appId}`, - "clientSecret": `${aadApp.secret}`, - "subscriptionId": `${inputs.subscriptionId}`, - "tenantId": `${inputs.azureSession.tenantId}`, - }); - } -} diff --git a/src/configure/configurers/provisioningConfigurer.ts b/src/configure/configurers/provisioningConfigurer.ts deleted file mode 100644 index a2ee6d74..00000000 --- a/src/configure/configurers/provisioningConfigurer.ts +++ /dev/null @@ -1,304 +0,0 @@ -import * as fse from 'fs-extra'; -import * as os from 'os'; -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { UserCancelledError } from 'vscode-azureextensionui'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { IProvisioningServiceClient } from "../clients/IProvisioningServiceClient"; -import { ProvisioningServiceClientFactory } from "../clients/provisioningServiceClientFactory"; -import { sleepForMilliSeconds } from '../helper/commonHelper'; -import { ControlProvider } from '../helper/controlProvider'; -import { GraphHelper } from '../helper/graphHelper'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { ExtendedInputDescriptor, InputDataType } from "../model/Contracts"; -import { WizardInputs } from "../model/models"; -import { CompletePipelineConfiguration, DraftPipelineConfiguration, File, ProvisioningConfiguration } from "../model/provisioningConfiguration"; -import { RemotePipelineTemplate } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import { IProvisioningConfigurer } from './IProvisioningConfigurer'; - -// tslint:disable-next-line:interface-name -interface DraftFile { - content: string; - path: string; // This path will be one returned by provisioning service and it will based on linux - absPath: string; // This is absolute path of file for native OS -} - -const Layer: string = "ProvisioningConfigurer"; -export class ProvisioningConfigurer implements IProvisioningConfigurer { - private provisioningServiceClient: IProvisioningServiceClient; - private queuedPipelineUrl: string; - private refreshTime: number = 5 * 1000; - private maxNonStatusRetry: number = 60; // retries for max 5 min - private localGitRepoHelper: LocalGitRepoHelper; - private filesToCommit: DraftFile[] = []; - private committedWorkflow: string; - private tempWorkflowDirPath: string; - - constructor(localGitRepoHelper: LocalGitRepoHelper) { - this.localGitRepoHelper = localGitRepoHelper; - } - - public async queueProvisioningPipelineJob(provisioningConfiguration: ProvisioningConfiguration, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - const OrgAndRepoDetails = wizardInputs.sourceRepository.repositoryId.split('/'); - return await this.provisioningServiceClient.createProvisioningConfiguration(provisioningConfiguration, OrgAndRepoDetails[0], OrgAndRepoDetails[1]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToCreateProvisioningPipeline, error); - throw error; - } - } - - public async getProvisioningPipeline(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - try { - this.provisioningServiceClient = await ProvisioningServiceClientFactory.getClient(); - return await this.provisioningServiceClient.getProvisioningConfiguration(jobId, githubOrg, repository); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnabletoGetProvisioningPipeline, error); - throw error; - } - } - - public async awaitProvisioningPipelineJob(jobId: string, githubOrg: string, repository: string, wizardInputs: WizardInputs): Promise { - let statusNotFound: number = 0; - const provisioningServiceResponse = await this.getProvisioningPipeline(jobId, githubOrg, repository, wizardInputs); - if (provisioningServiceResponse && provisioningServiceResponse.result) { - if (provisioningServiceResponse.result.status === "Queued" || provisioningServiceResponse.result.status == "InProgress") { - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else if (provisioningServiceResponse.result.status === "Failed") { - throw new Error(provisioningServiceResponse.result.message); - } else { - return provisioningServiceResponse; - } - } else { - if (statusNotFound < this.maxNonStatusRetry) { - statusNotFound++; - await sleepForMilliSeconds(this.refreshTime); - return await this.awaitProvisioningPipelineJob(jobId, githubOrg, repository, wizardInputs); - } else { - throw new Error("Failed to receive queued pipeline provisioning job status"); - } - } - } - - public async browseQueuedWorkflow(): Promise { - let displayMessage: string; - if (this.committedWorkflow.length > 1) { - displayMessage = Messages.GithubWorkflowSetupMultiFile; - } else { - displayMessage = Messages.GithubWorkflowSetup; - } - - new ControlProvider().showInformationBox("Browse queued workflow", utils.format(displayMessage, this.committedWorkflow), Messages.browseWorkflow) - .then((action: string) => { - if (action && action.toLowerCase() === Messages.browseWorkflow.toLowerCase()) { - telemetryHelper.setTelemetry(TelemetryKeys.BrowsePipelineClicked, 'true'); - vscode.env.openExternal(vscode.Uri.parse(this.queuedPipelineUrl)); - } - }); - } - - public async postSteps(provisioningConfiguration: ProvisioningConfiguration, draftPipelineConfiguration: DraftPipelineConfiguration, inputs: WizardInputs): Promise { - await this.populateFilesToCommit(draftPipelineConfiguration); - await this.showPipelineFiles(); - const displayMessage = (this.filesToCommit.length > 1) ? Messages.modifyAndCommitMultipleFiles : Messages.modifyAndCommitFile; - const commitOrDiscard = await new ControlProvider().showInformationBox( - "Commit or discard", - utils.format(displayMessage, Messages.commitAndPush, inputs.sourceRepository.branch, inputs.sourceRepository.remoteName), - Messages.commitAndPush, - Messages.discardPipeline); - let provisioningServiceResponse: ProvisioningConfiguration; - if (!!commitOrDiscard && commitOrDiscard.toLowerCase() === Messages.commitAndPush.toLowerCase()) { - telemetryHelper.setCurrentStep('ConfiguringPreRequisiteParamsForCompleteMode'); - if (this.getInputDescriptor(inputs, "azureAuth")) { - await this.createSPN(inputs); - } - provisioningServiceResponse = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.ConfiguringGithubWorkflowAndDeployment }, - async () => { - try { - telemetryHelper.setCurrentStep('QueuedCompleteProvisioiningPipeline'); - provisioningConfiguration.pipelineConfiguration = await this.createFilesToCheckin(draftPipelineConfiguration.id, draftPipelineConfiguration.type); - const completeProvisioningSvcResp = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (completeProvisioningSvcResp.id != "") { - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - telemetryHelper.setCurrentStep('AwaitCompleteProvisioningPipeline'); - return await this.awaitProvisioningPipelineJob(completeProvisioningSvcResp.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.RemotePipelineConfiguringFailed, error); - vscode.window.showErrorMessage(utils.format(Messages.ConfiguringGitubWorkflowFailed, error.message)); - return null; - } - }); - } else { - telemetryHelper.setTelemetry(TelemetryKeys.PipelineDiscarded, 'true'); - await this.moveWorkflowFilesToLocalRepo(); - throw new UserCancelledError(Messages.operationCancelled); - } - - fse.removeSync(this.tempWorkflowDirPath); - if (provisioningServiceResponse != undefined) { - this.setQueuedPipelineUrl(provisioningServiceResponse, inputs); - } else { - throw new Error("Failed to configure provisoining pipeline"); - } - } - - public async preSteps(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs): Promise { - return await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: Messages.GeneratingWorkflowFiles }, async () => { - try { - telemetryHelper.setCurrentStep('QueuedDraftProvisioningPipeline'); - // Initially send the provisioning request in draft mode to get workflow files - const provisioningServiceDraftModeResponse: ProvisioningConfiguration = await this.queueProvisioningPipelineJob(provisioningConfiguration, inputs); - if (provisioningServiceDraftModeResponse.id != "") { - // Monitor the provisioning pipeline - telemetryHelper.setCurrentStep('AwaitDraftProvisioningPipeline'); - const OrgAndRepoDetails = inputs.sourceRepository.repositoryId.split('/'); - return await this.awaitProvisioningPipelineJob(provisioningServiceDraftModeResponse.id, OrgAndRepoDetails[0], OrgAndRepoDetails[1], inputs); - } else { - throw new Error("Failed to configure provisioning pipeline"); - } - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ConfiguringDraftPipelineFailed, error); - throw error; - } - }); - } - - public async showPipelineFiles(): Promise { - this.filesToCommit.forEach(async (file) => { - await this.localGitRepoHelper.writeFileContent(file.content, file.absPath); - await vscode.window.showTextDocument(vscode.Uri.file(file.absPath), { preview: false }); - }); - } - - public setQueuedPipelineUrl(provisioningConfiguration: ProvisioningConfiguration, inputs: WizardInputs) { - const commitId = (provisioningConfiguration.result.pipelineConfiguration as CompletePipelineConfiguration).commitId; - this.queuedPipelineUrl = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}/checks`; - this.committedWorkflow = `https://github.com/${inputs.sourceRepository.repositoryId}/commit/${commitId}`; - } - - public async populateFilesToCommit(draftPipelineConfiguration: DraftPipelineConfiguration): Promise { - let destination: string; - this.tempWorkflowDirPath = fse.mkdtempSync(os.tmpdir().concat(Path.sep)); - for (const file of draftPipelineConfiguration.files) { - const pathList = file.path.split("/"); - const filePath: string = pathList.join(Path.sep); - destination = await this.getPathToFile(Path.basename(filePath), Path.dirname(filePath)); - const decodedData = new Buffer(file.content, 'base64').toString('utf-8'); - this.filesToCommit.push({ absPath: destination, content: decodedData, path: file.path } as DraftFile); - } - } - - public async createPreRequisiteParams(wizardInputs: WizardInputs): Promise { - // Create armAuthToken - wizardInputs.pipelineConfiguration.params["armAuthToken"] = "Bearer " + await GraphHelper.getAccessToken(wizardInputs.azureSession); - } - - public async createSPN(wizardInputs: WizardInputs): Promise { - // Create SPN and ACRResource group for reuseACR flow set to false - const inputDescriptor = this.getInputDescriptor(wizardInputs, "azureAuth"); - const createResourceGroup = InputControl.getInputDescriptorProperty(inputDescriptor, "resourceGroup", wizardInputs.pipelineConfiguration.params); - const location = InputControl.getInputDescriptorProperty(inputDescriptor, "location", wizardInputs.pipelineConfiguration.params); - if (createResourceGroup && createResourceGroup.length > 0 && createResourceGroup[0] != "" && location && location.length > 0 && location[0] != "") { - await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingResourceGroup }, - async () => { - try { - // TODO: Add support for multiple resource group - return await new ArmRestClient(wizardInputs.azureSession).createResourceGroup(wizardInputs.subscriptionId, createResourceGroup[0], location[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.ResourceGroupCreationFailed, error); - throw error; - } - }); - } - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", wizardInputs.pipelineConfiguration.params); - if (scope && scope.length > 0 && scope[0] != "") { - wizardInputs.pipelineConfiguration.params["azureAuth"] = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: Messages.CreatingSPN }, - async () => { - try { - // TODO: Need to add support for array of scope - return await this.getAzureSPNSecret(wizardInputs, scope[0]); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.SPNCreationFailed, error); - throw error; - } - }); - } - } - - private getInputDescriptor(wizardInputs: WizardInputs, inputId: string): ExtendedInputDescriptor { - const template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let inputDataType: InputDataType; - switch (inputId) { - case "azureAuth": - inputDataType = InputDataType.Authorization; - break; - default: - return undefined; - } - - return template.parameters.inputs.find((value) => (value.type === inputDataType && value.id === inputId)); - } - - private async getAzureSPNSecret(inputs: WizardInputs, scope?: string): Promise { - const aadAppName = GraphHelper.generateAadApplicationName(inputs.sourceRepository.remoteName, 'github'); - const aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - return JSON.stringify({ - scheme: 'ServicePrincipal', - parameters: { - serviceprincipalid: `${aadApp.appId}`, - serviceprincipalkey: `${aadApp.secret}`, - subscriptionId: `${inputs.subscriptionId}`, - tenantid: `${inputs.azureSession.tenantId}`, - } - }); - } - - // tslint:disable-next-line:no-reserved-keywords - private async createFilesToCheckin(id: string, type: string): Promise { - const files: File[] = []; - for (const file of this.filesToCommit) { - const fileContent = await this.localGitRepoHelper.readFileContent(file.absPath); - const encodedContent = new Buffer(fileContent, 'utf-8').toString('base64'); - files.push({ path: file.path, content: encodedContent }); - } - - return { - id, - type, - files, - } as DraftPipelineConfiguration; - } - - private async moveWorkflowFilesToLocalRepo(): Promise { - const gitRootDirectory: string = await this.localGitRepoHelper.getGitRootDirectory(); - for (const file of this.filesToCommit) { - const filePathList = file.path.split("/"); - const filePath: string = filePathList.join(Path.sep); - const filePathToLocalRepo: string = Path.join(gitRootDirectory, filePath); - fse.moveSync(file.absPath, filePathToLocalRepo); - await vscode.window.showTextDocument(vscode.Uri.file(filePathToLocalRepo), { preview: false }); - } - fse.removeSync(this.tempWorkflowDirPath); - } - - private async getPathToFile(fileName: string, directory: string) { - const dirList = directory.split("/"); // Hardcoded as provisioning service is running on linux and we cannot use Path.sep as it is machine dependent - const directoryPath: string = Path.join(this.tempWorkflowDirPath, dirList.join(Path.sep)); - fse.mkdirpSync(directoryPath); - telemetryHelper.setTelemetry(TelemetryKeys.WorkflowFileName, fileName); - return Path.join(directoryPath, fileName); - } -} diff --git a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts b/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts deleted file mode 100644 index 253569f8..00000000 --- a/src/configure/configurers/remoteGitHubWorkflowConfigurer.ts +++ /dev/null @@ -1,247 +0,0 @@ -import * as Path from 'path'; -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { GithubClient } from '../clients/github/githubClient'; -import { ITemplateServiceClient } from '../clients/ITemplateServiceClient'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { LocalGitRepoHelper } from '../helper/LocalGitRepoHelper'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { Asset, ConfigurationStage, InputDataType } from "../model/Contracts"; -import { AzureSession, ParsedAzureResourceId, StringMap, WizardInputs } from "../model/models"; -import { RemotePipelineTemplate } from "../model/templateModels"; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { InputControl } from '../templateInputHelper/InputControl'; -import * as templateConverter from '../utilities/templateConverter'; -import * as nodeVersionConverter from '../utilities/webAppNodeVersionConverter'; -import { LocalGitHubWorkflowConfigurer } from './localGithubWorkflowConfigurer'; - -export interface File { - path: string; - content: string; -} - -const Layer: string = "RemoteGitHubWorkflowConfigurer"; - -export class RemoteGitHubWorkflowConfigurer extends LocalGitHubWorkflowConfigurer { - private azureSession: AzureSession; - private assets: { [key: string]: any } = {}; - private inputs: WizardInputs; - private secrets: { [key: string]: any } = {}; - private variables: { [key: string]: any } = {}; - private system: { [key: string]: any } = {}; - private filesToCommit: File[] = []; - private mustacheContext: StringMap; - private template: RemotePipelineTemplate; - private localGitHelper: LocalGitRepoHelper; - private templateServiceClient: ITemplateServiceClient; - - constructor(azureSession: AzureSession, localGitHelper: LocalGitRepoHelper) { - super(localGitHelper); - this.azureSession = azureSession; - this.localGitHelper = localGitHelper; - } - - public async getInputs(wizardInputs: WizardInputs): Promise { - this.inputs = wizardInputs; - this.githubClient = new GithubClient(wizardInputs.githubPATToken, wizardInputs.sourceRepository.remoteUrl); - this.templateServiceClient = await TemplateServiceClientFactory.getClient(); - this.template = wizardInputs.pipelineConfiguration.template as RemotePipelineTemplate; - let extendedPipelineTemplate; - try { - extendedPipelineTemplate = await this.templateServiceClient.getTemplateConfiguration(this.template.id, wizardInputs.pipelineConfiguration.params); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateConfiguration, error); - throw error; - - } - this.template.configuration = templateConverter.convertToLocalMustacheExpression(extendedPipelineTemplate.configuration); - - this.template.configuration.assets.forEach((asset: Asset) => { - if (!asset.stage) { - asset.stage = ConfigurationStage.Pre; - } - }); - - this.system["sourceRepository"] = wizardInputs.sourceRepository; - - this.mustacheContext = { - inputs: wizardInputs.pipelineConfiguration.params, - variables: this.variables, - assets: this.assets, - secrets: this.secrets, - system: this.system - }; - - for (let variable of this.template.configuration.variables) { - let expression = variable.value; - let value = MustacheHelper.render(expression, this.mustacheContext); - this.variables[variable.id] = value; - } - } - - public async createPreRequisites(inputs: WizardInputs, azureResourceClient: AzureResourceClient) { - return null; - } - - public async createAssets(stage: ConfigurationStage = ConfigurationStage.Pre) { - let assets = this.template.configuration.assets; - if (!!assets && assets.length > 0) { - for (let asset of assets) { - if (asset.stage === stage) { - asset = MustacheHelper.renderObject(asset, this.mustacheContext); - try { - await this.createAssetInternal(asset); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - } - } - } - } - - public async getPipelineFilesToCommit(inputs: WizardInputs): Promise { - let workflowFile = await this.getWorkflowFile(inputs); - this.filesToCommit.push(workflowFile); - this.filesToCommit.forEach(async (file) => { - await this.localGitHelper.addContentToFile(file.content, file.path); - await vscode.window.showTextDocument(vscode.Uri.file(file.path)); - }); - return this.filesToCommit.map(x => x.path); - } - - private async createAssetInternal(asset: Asset): Promise { - if (!!asset) { - switch (asset.type) { - case "AzureCredentials:SPN": - const subscriptionId = this.inputs.subscriptionId; - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - const inputDescriptor = this.template.parameters.inputs.find((value) => (value.type === InputDataType.Authorization && value.id === "azureAuth")); - const scope = InputControl.getInputDescriptorProperty(inputDescriptor, "scope", this.inputs.pipelineConfiguration.params); - return this.getAzureSPNSecret(this.inputs, scope); - }); - break; - case "SetGHSecret": - let secretKey: string = asset.inputs["secretKey"]; - let secretValue: string = asset.inputs["secretvalue"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.settingUpGithubSecrets - }, - async () => { - await this.githubClient.createOrUpdateGithubSecret(secretKey, secretValue); - } - ); - this.secrets[asset.id] = "{{ secrets." + secretKey + " }}"; - break; - case "commitFile:Github": - let source: string = asset.inputs["source"]; - let destination: string = asset.inputs["destination"]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingTemplateFileAsset - }, - async () => { - destination = await this.getPathToFile(this.localGitHelper, Path.basename(destination), Path.dirname(destination)); - - let fileContent = await this.getTemplateFile(source); - this.filesToCommit.push({ path: destination, content: fileContent }); - } - ); - - this.assets[asset.id] = destination; - break; - case "LinuxWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Linux&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "WindowsWebAppNodeVersionConverter": - { - let nodeVersion: string = asset.inputs["webAppRuntimeNodeVersion"]; - const armUri = "/providers/Microsoft.Web/availableStacks?osTypeSelected=Windows&api-version=2019-08-01"; - this.assets[asset.id] = await nodeVersionConverter.webAppRuntimeNodeVersionConverter(nodeVersion, armUri, this.azureSession); - } - break; - case "AzureCredentials:PublishProfile": - { - let resourceId = asset.inputs["resourceId"]; - let parsedResourceId = new ParsedAzureResourceId(resourceId); - let subscriptionId = parsedResourceId.subscriptionId; - - this.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(this.azureSession.credentials, this.azureSession.environment, this.azureSession.tenantId, subscriptionId); - return await appServiceClient.getWebAppPublishProfileXml(resourceId); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzurePublishProfileCreationFailure, error); - throw error; - } - }); - } - break; - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - private async getWorkflowFile(inputs: WizardInputs): Promise { - let pipelineDefinition = MustacheHelper.renderObject(this.template.configuration.pipelineDefinition, this.mustacheContext); - let workflowFileContent: string; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.gettingWorkflowFile - }, - async () => { - workflowFileContent = await this.getTemplateFile(pipelineDefinition.templateFile); - } - ); - let workFlowFileName: string = pipelineDefinition.destinationFileName; - workFlowFileName = await this.getPathToPipelineFile(inputs, this.localGitHelper, workFlowFileName); - inputs.pipelineConfiguration.filePath = workFlowFileName; - return { - path: workFlowFileName, - content: workflowFileContent - }; - } - - private async getTemplateFile(fileName: string): Promise { - try { - let result = await this.templateServiceClient.getTemplateFile(this.template.id, fileName); - if (result.length > 0) { - let templateFile = result.find((value) => value.id === fileName); - if (templateFile) { - let content = templateConverter.convertToLocalMustacheExpression(templateFile.content); - return MustacheHelper.render(content, this.mustacheContext); - } - } - throw new Error(utils.format(Messages.templateFileNotFound, fileName)); - } catch (error) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateFile, error); - throw error; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/AssetHandler.ts b/src/configure/helper/AssetHandler.ts deleted file mode 100644 index ede21d64..00000000 --- a/src/configure/helper/AssetHandler.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { AppServiceClient } from '../clients/azure/appServiceClient'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { UniqueResourceNameSuffix } from '../configure'; -import { TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, TemplateAsset, TemplateAssetType, TemplateParameterType } from '../model/templateModels'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { GraphHelper } from './graphHelper'; -import { SodiumLibHelper } from './sodium/SodiumLibHelper'; -import { telemetryHelper } from './telemetryHelper'; -import { TemplateParameterHelper } from './templateParameterHelper'; - -const Layer = "AssetCreationHandler"; - -export class AssetHandler { - // tslint:disable-next-line:no-reserved-keywords - public async createAssets(assets: TemplateAsset[], inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (inputs.pipelineConfiguration.template.label === "Containerized application to AKS") { - if (!!assets && assets.length > 0) { - for (let asset of assets) { - await this.createAssetInternal(asset, inputs, createAsset); - } - } - } - } - - // tslint:disable-next-line:no-reserved-keywords - private async createAssetInternal(asset: TemplateAsset, inputs: WizardInputs, createAsset: (name: string, type: TemplateAssetType, data: any, inputs: WizardInputs) => Promise): Promise { - if (!!asset) { - switch (asset.type) { - case TemplateAssetType.AzureARMServiceConnection: - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let scope = inputs.pipelineConfiguration.params["targetResource"].id; - let aadAppName = GraphHelper.generateAadApplicationName(inputs.organizationName, inputs.project.name); - let aadApp = await GraphHelper.createSpnAndAssignRole(inputs.azureSession, aadAppName, scope); - // Use param name for first azure resource param - let serviceConnectionName = `${inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => parameter.type === TemplateParameterType.GenericAzureResource).name]}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, { "aadApp": aadApp, "scope": scope }, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.AzureARMPublishProfileServiceConnection: - let targetWebAppResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.WebApp); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingAzureServiceConnection, inputs.subscriptionId) - }, - async () => { - try { - // find LCS of all azure resource params - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - let publishProfile = await appServiceClient.getWebAppPublishProfileXml(inputs.targetResource.resource.id); - let serviceConnectionName = `${targetWebAppResource.name}-${UniqueResourceNameSuffix}`; - return await createAsset(serviceConnectionName, asset.type, publishProfile, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AzureServiceConnectionCreateFailure, error); - throw error; - } - }); - break; - // uses azure resource client to get the required details, and then calls into configurer.createServiceConnection(serviceConnectionType, properties: property bag with all the required information that are needed/available to create service connection.) - case TemplateAssetType.AKSKubeConfigServiceConnection: - case TemplateAssetType.GitHubAKSKubeConfig: - let targetAksResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.AKS); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingKubernetesConnection, targetAksResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let base64EncodedKubeConfig: { kubeconfigs: Array<{ name: string, value: string }> } = await armClient.getAksKubeConfig(targetAksResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAksResource.name); - return await createAsset(assetName, asset.type, SodiumLibHelper.decodeFromBase64(JSON.stringify(base64EncodedKubeConfig.kubeconfigs[0].value)), inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.ACRServiceConnection: - let targetAcrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, targetAcrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(targetAcrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(targetAcrResource.name); - return await createAsset(assetName, asset.type, registryCreds, inputs); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - case TemplateAssetType.GitHubRegistryUsername: - case TemplateAssetType.GitHubRegistryPassword: - let acrResource = TemplateParameterHelper.getParameterValueForTargetResourceType(inputs.pipelineConfiguration, TargetResourceType.ACR); - inputs.pipelineConfiguration.assets[asset.id] = await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: utils.format(Messages.creatingContainerRegistryConnection, acrResource.name) - }, - async () => { - try { - let armClient = new ArmRestClient(inputs.azureSession); - let registryCreds: { username: string, passwords: Array<{ name: string, value: string }> } = await armClient.getAcrCredentials(acrResource.id); - let assetName = AssetHandler.getSanitizedUniqueAssetName(acrResource.name); - if (asset.type === TemplateAssetType.GitHubRegistryUsername) { - return await createAsset(assetName + "_username", asset.type, registryCreds.username, inputs); - } - else { - let password = !!registryCreds.passwords && registryCreds.passwords.length > 0 ? registryCreds.passwords[0].value : null; - if (!password) { - throw Messages.unableToFetchPasswordOfContainerRegistry; - } - - return await createAsset(assetName + "_password", asset.type, password, inputs); - } - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.AssetCreationFailure, error); - throw error; - } - }); - break; - - case TemplateAssetType.File: - break; - case TemplateAssetType.GitHubARM: - case TemplateAssetType.GitHubARMPublishProfile: - default: - throw new Error(utils.format(Messages.assetOfTypeNotSupported, asset.type)); - } - } - } - - /** - * @param assetName : the asset name you need sanitized - * @returns sanitized asset name and makes it unique by appending 5 digit random alpha numeric string to asset name. - */ - public static getSanitizedUniqueAssetName(assetName: string): string { - assetName = assetName + "_" + UniqueResourceNameSuffix; - assetName = assetName.replace(/\W/g, ''); - return assetName; - } -} \ No newline at end of file diff --git a/src/configure/helper/DataSourceHandler.ts b/src/configure/helper/DataSourceHandler.ts deleted file mode 100644 index b00363b8..00000000 --- a/src/configure/helper/DataSourceHandler.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RestClient } from "../clients/restClient"; -import { ParsedAzureResourceId, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds } from "../model/templateModels"; - -export class DataSourceHandler { - public getResultFromPreDefinedDataSourceId(dataSourceId: string, inputs: WizardInputs): Promise { - switch (dataSourceId) { - case PreDefinedDataSourceIds.AKS: - let restClient = new RestClient(inputs.azureSession.credentials); - let parsedResourceId = new ParsedAzureResourceId(inputs.pipelineConfiguration.params[(inputs.pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((param) => { return param.dataSourceId === PreDefinedDataSourceIds.AKS; }).name].id); - let kubeConfig = restClient.sendRequestWithHttpOperationResponse( - { - url: inputs.azureSession.environment.portalUrl + `/subscriptions/${parsedResourceId.subscriptionId}/resourceGroups/${parsedResourceId.resourceGroup}/providers/Microsoft.ContainerService/managedClusters/${parsedResourceId.resourceName}/listClusterAdminCredential?api-version=2020-01-01`, - method: "POST", - deserializationMapper: null, - serializationMapper: null - }); - return kubeConfig; - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.LinuxContainerApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - case PreDefinedDataSourceIds.WindowsApp: - default: - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/helper/LocalGitRepoHelper.ts b/src/configure/helper/LocalGitRepoHelper.ts deleted file mode 100644 index 207bcf9f..00000000 --- a/src/configure/helper/LocalGitRepoHelper.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as Q from 'q'; -import * as git from 'simple-git/promise'; -import { RemoteWithoutRefs } from 'simple-git/typings/response'; -import * as vscode from 'vscode'; -import { Configurer } from '../configurers/configurerBase'; -import { GitBranchDetails, GitRepositoryParameters, MustacheContext, WizardInputs } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { TracePoints } from '../resources/tracePoints'; -import { AzureDevOpsHelper } from './devOps/azureDevOpsHelper'; -import { GitHubProvider } from './gitHubHelper'; -import { telemetryHelper } from "./telemetryHelper"; -import * as templateHelper from './templateHelper'; - -const Layer = 'LocalGitRepoHelper'; - -export class LocalGitRepoHelper { - - public static GetHelperInstance(repositoryPath: string): LocalGitRepoHelper { - var repoService = new LocalGitRepoHelper(); - repoService.initialize(repositoryPath); - - let gitFolderExists = fs.existsSync(path.join(repositoryPath, ".git")); - telemetryHelper.setTelemetry(TelemetryKeys.GitFolderExists, gitFolderExists.toString()); - - return repoService; - } - - public static async GetAvailableFileName(fileName: string, repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - if (files.indexOf(fileName) < 0) { - deferred.resolve(fileName); - } - else { - for (let i = 1; i < 100; i++) { - let increamentalFileName = LocalGitRepoHelper.getIncreamentalFileName(fileName, i); - if (files.indexOf(increamentalFileName) < 0) { - deferred.resolve(increamentalFileName); - } - } - } - }); - - return deferred.promise; - } - - private static getIncreamentalFileName(fileName: string, count: number): string { - return fileName.substr(0, fileName.indexOf('.')).concat(` (${count})`, fileName.substr(fileName.indexOf('.'))); - } - - private gitReference: git.SimpleGit; - private constructor() { - } - - public async getUsername(): Promise { - let username = await this.gitReference.raw([ - 'config', - 'user.name' - ]); - - return username; - } - - public async isGitRepository(): Promise { - try { - await this.gitReference.status(); - return true; - } - catch (error) { - return false; - } - } - - public async getGitBranchDetails(): Promise { - let status = await this.gitReference.status(); - let branch = status.current; - let remote = status.tracking ? status.tracking.substr(0, status.tracking.indexOf(branch) - 1) : null; - - return { - branch: branch, - remoteName: remote - }; - } - - public async getGitRemotes(): Promise { - return this.gitReference.getRemotes(false); - } - - public async getGitRemoteUrl(remoteName: string): Promise { - let remoteUrl = await this.gitReference.remote(["get-url", remoteName]); - if (remoteUrl) { - remoteUrl = (remoteUrl).trim(); - if (remoteUrl[remoteUrl.length - 1] === '/') { - remoteUrl = remoteUrl.substr(0, remoteUrl.length - 1); - } - } - - if (AzureDevOpsHelper.isAzureReposUrl(remoteUrl)) { - remoteUrl = AzureDevOpsHelper.getFormattedRemoteUrl(remoteUrl); - } - else if (GitHubProvider.isGitHubUrl(remoteUrl)) { - remoteUrl = GitHubProvider.getFormattedRemoteUrl(remoteUrl); - } - return remoteUrl; - } - - /** - * - * @param pathToFile : local path of yaml pipeline in the extension - * @param content: inputs required to be filled in the yaml pipelines - * @returns: thenable object which resolves once all files are added to the repository - */ - public async addContentToFile(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - await vscode.workspace.saveAll(true); - return pathToFile; - } - - /** - * commits yaml pipeline file into the local repo and pushes the commit to remote branch. - * @param files : array of local path of yaml files in the repository - * @returns: thenable string which resolves to commitId once commit is pushed to remote branch, and failure message if unsuccessful - */ - public async commitAndPushPipelineFile(files: string[], repositoryDetails: GitRepositoryParameters, commitMessage: string): Promise { - try { - await this.gitReference.add(files); - await this.gitReference.commit(commitMessage, files); - let gitLog = await this.gitReference.log(); - - if (repositoryDetails.remoteName && repositoryDetails.branch) { - await this.gitReference.push(repositoryDetails.remoteName, repositoryDetails.branch, { - "--set-upstream": null - }); - } - else { - throw new Error(Messages.cannotAddFileRemoteMissing); - } - - return gitLog.latest.hash; - - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.CommitAndPushPipelineFileFailed, error); - throw error; - } - } - - public async getGitRootDirectory(): Promise { - let gitRootDir = await this.gitReference.revparse(["--show-toplevel"]); - return path.normalize(gitRootDir.trim()); - } - - public async initializeGitRepository(remoteName: string, remoteUrl: string, filesToExcludeRegex?: string): Promise { - try { - let isGitRepository = await this.isGitRepository(); - - if (!isGitRepository) { - await this.gitReference.init(); - } - - try { - // Try to see if there are any commits - await this.gitReference.log(); - } - catch (error) { - // Commit all files if there are not commits on this branch - await this.gitReference.add(`:!${filesToExcludeRegex}`); - await this.gitReference.commit("Initialized git repository"); - } - - await this.gitReference.addRemote(remoteName, remoteUrl); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.InitializeGitRepositoryFailed, error); - throw error; - } - } - - public async createAndDisplayManifestFile(manifestFile: string, pipelineConfigurer: Configurer, filesToCommit: string[], inputs: WizardInputs, targetfileName: string = null) { - let targetFile: string = targetfileName ? targetfileName : manifestFile; - let manifestPath: string = path.join(path.dirname(__dirname), "/templates/dependencies/"); - let mustacheContext = new MustacheContext(inputs); - let manifestFilePath: string; - - manifestFilePath = await pipelineConfigurer.getPathToManifestFile(inputs, this, targetFile + '.yml'); - inputs.pipelineConfiguration.assets[manifestFile] = path.relative(await this.getGitRootDirectory(), manifestFilePath).split(path.sep).join('/'); - filesToCommit.push(manifestFilePath); - await this.addContentToFile( - await templateHelper.renderContent(manifestPath + manifestFile + '.yml', mustacheContext), - manifestFilePath); - await vscode.window.showTextDocument(vscode.Uri.file(manifestFilePath)); - } - - public async readFileContent(pathToFile: string): Promise { - const buf = fs.readFileSync(pathToFile); - return buf.toString(); - } - - public async writeFileContent(content: string, pathToFile: string): Promise { - fs.writeFileSync(pathToFile, content); - return pathToFile; - } - - private initialize(repositoryPath: string): void { - this.gitReference = git(repositoryPath); - } -} diff --git a/src/configure/helper/azureSessionHelper.ts b/src/configure/helper/azureSessionHelper.ts deleted file mode 100644 index 127bacef..00000000 --- a/src/configure/helper/azureSessionHelper.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SubscriptionModels } from "azure-arm-resource"; -import { isNullOrUndefined } from "util"; -import { AzureSession, extensionVariables } from "../model/models"; -import { Messages } from "../resources/messages"; -import { WhiteListedError } from "../utilities/utilities"; - -export async function getSubscriptionSession(subscriptionId: string): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - let currentSubscription: { session: AzureSession, subscription: SubscriptionModels.Subscription } = extensionVariables.azureAccountExtensionApi.subscriptions - .find((subscription) => - subscription.subscription.subscriptionId.toLowerCase() === subscriptionId.toLowerCase()); - - // Fallback to first element - if (!currentSubscription) { - currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - } - - return currentSubscription.session; -} - -export async function getAzureSession(): Promise { - if (!(await extensionVariables.azureAccountExtensionApi.waitForSubscriptions())) { - throw new Error(Messages.AzureLoginError); - } - - const currentSubscription = extensionVariables.azureAccountExtensionApi.subscriptions[0]; - if (isNullOrUndefined(currentSubscription)) { - throw new WhiteListedError(Messages.NoAzureSubscriptionFound); - } - - return currentSubscription.session; -} \ No newline at end of file diff --git a/src/configure/helper/commonHelper.ts b/src/configure/helper/commonHelper.ts deleted file mode 100644 index ae0dacd9..00000000 --- a/src/configure/helper/commonHelper.ts +++ /dev/null @@ -1,110 +0,0 @@ -import Q = require('q'); -import * as util from 'util'; -import * as logger from '../../logger'; -import { GithubClient } from '../clients/github/githubClient'; -import { GitHubRepo } from '../model/models'; -import { Messages } from '../resources/messages'; - -const uuid = require('uuid/v4'); - -export async function sleepForMilliSeconds(timeInMs: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); -} - -export async function generateGitHubRepository(orgName: string, localPath: string, githubClient: GithubClient, isUserAccount: boolean = false): Promise { - let repoName = localPath.substring(localPath.lastIndexOf("\\") + 1).substring(localPath.lastIndexOf("/") + 1); - let repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - // Case : GitHub Repository name is same as the local repo - if (repoDetails) { - return repoDetails; - } - //Case: Local repository name is not available, therefore organization name has been appended - repoName = repoName + "_" + orgName; - repoDetails = await githubClient.createGithubRepo(orgName, repoName, isUserAccount) as GitHubRepo; - if (repoDetails) { - return repoDetails; - } - //Case: If the above two repository names are not available, uuid is also appended - return await githubClient.createGithubRepo(orgName, repoName + "_" + uuid().substr(0, 5), isUserAccount); -} - -export function generateDevOpsOrganizationName(userName: string, repositoryName: string): string { - let repositoryNameSuffix = repositoryName.replace("/", "-").trim(); - let organizationName = `${userName}-${repositoryNameSuffix}`; - - // Name cannot start or end with whitespaces, cannot start with '-', cannot contain characters other than a-z|A-Z|0-9 - organizationName = organizationName.trim().replace(/^[-]+/, '').replace(/[^a-zA-Z0-9-]/g, ''); - if (organizationName.length > 50) { - organizationName = organizationName.substr(0, 50); - } - - return organizationName; -} - -export function generateDevOpsProjectName(repositoryName?: string): string { - if (!repositoryName) { - return "AzurePipelines"; - } - - let repoParts = repositoryName.split("/"); - let suffix = repoParts[repoParts.length - 1]; - suffix = suffix.trim(); - // project name cannot end with . or _ - suffix = suffix.replace(/\.[\.]*$/, '').replace(/^_[_]*$/, ''); - - let projectName = `AzurePipelines-${suffix}`; - if (projectName.length > 64) { - projectName = projectName.substr(0, 64); - } - - return projectName; -} - -export function generateRandomPassword(length: number = 20): string { - var characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#%^*()-+"; - var charTypeSize = new Array(26, 26, 10, 10); - var charTypeStartIndex = new Array(0, 26, 52, 62); - var password = ""; - for (var x = 0; x < length; x++) { - var i = Math.floor(Math.random() * charTypeSize[x % 4]); - password += characters.charAt(i + charTypeStartIndex[x % 4]); - } - return password; -} - -export function stringCompareFunction(a: string, b: string): number { - a = a && a.toLowerCase(); - b = b && b.toLowerCase(); - if (a < b) { - return -1; - } - else if (a > b) { - return 1; - } - return 0; -} - -export async function executeFunctionWithRetry( - func: () => Promise, - retryCount: number = 20, - retryIntervalTimeInSec: number = 2, - errorMessage?: string): Promise { - let internalError = null; - for (; retryCount > 0; retryCount--) { - try { - let result = await func(); - return result; - } - catch (error) { - internalError = error; - logger.log(JSON.stringify(error)); - await Q.delay((resolve) => { resolve(); }, retryIntervalTimeInSec * 1000); - } - } - - throw errorMessage ? errorMessage.concat(util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError))) : util.format(Messages.retryFailedMessage, retryCount, JSON.stringify(internalError)); -} \ No newline at end of file diff --git a/src/configure/helper/controlProvider.ts b/src/configure/helper/controlProvider.ts deleted file mode 100644 index 706b6ce5..00000000 --- a/src/configure/helper/controlProvider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InputBoxOptions, QuickPickItem, window } from 'vscode'; -import { IAzureQuickPickOptions, UserCancelledError } from 'vscode-azureextensionui'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { extensionVariables } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -export class ControlProvider { - public async showQuickPick(listName: string, listItems: T[] | Thenable, options: IAzureQuickPickOptions, itemCountTelemetryKey?: string): Promise { - try { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, listName); - return await extensionVariables.ui.showQuickPick(listItems, options); - } - finally { - if (itemCountTelemetryKey) { - telemetryHelper.setTelemetry(itemCountTelemetryKey, (await listItems).length.toString()); - } - } - } - - public async showInputBox(inputName: string, options: InputBoxOptions): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, inputName); - return await extensionVariables.ui.showInputBox(options); - } - - public async showInformationBox(informationIdentifier: string, informationMessage: string, ...actions: string[]): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - if (!!actions && actions.length > 0) { - let result = await window.showInformationMessage(informationMessage, ...actions); - if (!result) { - throw new UserCancelledError(Messages.userCancelledExcecption); - } - - return result; - } - else { - return await window.showInformationMessage(informationMessage, ...actions); - } - - } - - public async showErrorMessage(informationIdentifier: string, errorMessage: string): Promise { - telemetryHelper.setTelemetry(TelemetryKeys.CurrentUserInput, informationIdentifier); - await window.showErrorMessage(errorMessage); - } -} diff --git a/src/configure/helper/devOps/azureDevOpsHelper.ts b/src/configure/helper/devOps/azureDevOpsHelper.ts deleted file mode 100644 index 14a5caa4..00000000 --- a/src/configure/helper/devOps/azureDevOpsHelper.ts +++ /dev/null @@ -1,171 +0,0 @@ -import * as path from 'path'; -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { Build, BuildDefinition, BuildDefinitionRepositoryProperties } from '../../model/azureDevOps'; -import { RepositoryProvider, WizardInputs } from '../../model/models'; -import { HostedVS2017QueueName } from '../../resources/constants'; -import { Messages } from '../../resources/messages'; -import { TracePoints } from '../../resources/tracePoints'; -import { telemetryHelper } from '../telemetryHelper'; - -const Layer: string = 'azureDevOpsHelper'; - -export class AzureDevOpsHelper { - private static AzureReposUrl = 'dev.azure.com/'; - private static SSHAzureReposUrl = 'ssh.dev.azure.com:v3/'; - private static VSOUrl = '.visualstudio.com/'; - private static SSHVsoReposUrl = 'vs-ssh.visualstudio.com:v3/'; - - private azureDevOpsClient: AzureDevOpsClient; - - constructor(azureDevOpsClient: AzureDevOpsClient) { - this.azureDevOpsClient = azureDevOpsClient; - } - - public static isAzureReposUrl(remoteUrl: string): boolean { - return (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Convert SSH based url to https based url as pipeline service doesn't accept SSH based URL - if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let details = AzureDevOpsHelper.getRepositoryDetailsFromRemoteUrl(remoteUrl); - return `https://${details.organizationName}${AzureDevOpsHelper.VSOUrl}/${details.projectName}/_git/${details.repositoryName}`; - } - - return remoteUrl; - } - - public static getRepositoryDetailsFromRemoteUrl(remoteUrl: string): { organizationName: string, projectName: string, repositoryName: string } { - if (remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.AzureReposUrl) + AzureDevOpsHelper.AzureReposUrl.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 4) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.AzureReposUrl}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[3].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) >= 0) { - let part = remoteUrl.substr(remoteUrl.indexOf(AzureDevOpsHelper.VSOUrl) + AzureDevOpsHelper.VSOUrl.length); - let organizationName = remoteUrl.substring(remoteUrl.indexOf('https://') + 'https://'.length, remoteUrl.indexOf('.visualstudio.com')); - let parts = part.split('/').filter((value) => !!value); - - if (parts.length === 4 && parts[0].toLowerCase() === 'defaultcollection') { - // Handle scenario where part is 'DefaultCollection//_git/' - parts = parts.slice(1); - } - - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${AzureDevOpsHelper.VSOUrl}, Parts: ${parts.slice(1).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: organizationName, projectName: parts[0].trim(), repositoryName: parts[2].trim() }; - } - else if (remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 || remoteUrl.indexOf(AzureDevOpsHelper.SSHVsoReposUrl) >= 0) { - let urlFormat = remoteUrl.indexOf(AzureDevOpsHelper.SSHAzureReposUrl) >= 0 ? AzureDevOpsHelper.SSHAzureReposUrl : AzureDevOpsHelper.SSHVsoReposUrl; - let part = remoteUrl.substr(remoteUrl.indexOf(urlFormat) + urlFormat.length); - let parts = part.split('/').filter((value) => !!value); - if (parts.length !== 3) { - telemetryHelper.logError(Layer, TracePoints.GetRepositoryDetailsFromRemoteUrlFailed, new Error(`RemoteUrlFormat: ${urlFormat}, Parts: ${parts.slice(2).toString()}, Length: ${parts.length}`)); - throw new Error(Messages.failedToDetermineAzureRepoDetails); - } - return { organizationName: parts[0].trim(), projectName: parts[1].trim(), repositoryName: parts[2].trim() }; - } - else { - throw new Error(Messages.notAzureRepoUrl); - } - } - - public async createAndRunPipeline(pipelineName: string, inputs: WizardInputs): Promise { - try { - let buildDefinitionPayload = await this.getBuildDefinitionPayload(pipelineName, inputs); - let definition = await this.azureDevOpsClient.createBuildDefinition(inputs.organizationName, buildDefinitionPayload); - let build = await this.azureDevOpsClient.queueBuild(inputs.organizationName, this.getQueueBuildPayload(inputs, definition.id, definition.project.id)); - return build; - } - catch (error) { - throw new Error(util.format(Messages.failedToCreateAzurePipeline, error.message)); - } - } - - private async getBuildDefinitionPayload(pipelineName: string, inputs: WizardInputs): Promise { - let queueId = await this.getAgentQueueId(inputs.organizationName, inputs.project.name, HostedVS2017QueueName); - let repositoryProperties: BuildDefinitionRepositoryProperties = null; - let properties = { 'source': 'ms-azure-devops.azure-pipelines' }; - - if (inputs.sourceRepository.repositoryProvider === RepositoryProvider.Github) { - repositoryProperties = { - apiUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}`, - branchesUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/branches`, - cloneUrl: inputs.sourceRepository.remoteUrl, - connectedServiceId: inputs.sourceRepository.serviceConnectionId, - defaultBranch: inputs.sourceRepository.branch, - fullName: inputs.sourceRepository.repositoryName, - refsUrl: `https://api.github.com/repos/${inputs.sourceRepository.repositoryId}/git/refs` - }; - } - - return { - name: pipelineName, - type: 2, //YAML process type - quality: 1, // Defintion=1, Draft=0 - path: "\\", //Folder path of build definition. Root folder in this case - project: { - id: inputs.project.id, - name: inputs.project.name - }, - process: { - type: 2, - yamlFileName: path.basename(inputs.pipelineConfiguration.filePath) // As required, it will be at the root location and should be same as committed pipeline file - }, - queue: { - id: queueId // Default queue Hosted VS 2017. This value is overriden by queue specified in YAML - }, - triggers: [ - { - triggerType: 2, // Continuous integration trigger type - settingsSourceType: 2, // Use trigger source as specified in YAML - batchChanges: false - } - ], - repository: { - id: inputs.sourceRepository.repositoryId, - name: inputs.sourceRepository.repositoryName, - type: inputs.sourceRepository.repositoryProvider, - defaultBranch: inputs.sourceRepository.branch, - url: inputs.sourceRepository.remoteUrl, - properties: repositoryProperties - }, - properties: properties - }; - } - - private async getAgentQueueId(organizationName: string, projectName: string, poolName: string): Promise { - let queues = await this.azureDevOpsClient.getAgentQueues(organizationName, projectName); - let queueId: number = queues.length > 0 ? queues[0].id : null; - - for (let queue of queues) { - if (queue.pool && queue.pool.name && queue.pool.name.toLowerCase() === poolName.toLowerCase()) { - queueId = queue.id; - break; - } - } - - if (queueId !== null) { - return queueId; - } - - throw new Error(util.format(Messages.noAgentQueueFound, poolName)); - } - - private getQueueBuildPayload(inputs: WizardInputs, buildDefinitionId: number, projectId: string): Build { - return { - id: '', - definition: { id: buildDefinitionId }, - project: { id: projectId }, - sourceBranch: inputs.sourceRepository.branch, - sourceVersion: inputs.sourceRepository.commitId - }; - } -} \ No newline at end of file diff --git a/src/configure/helper/devOps/serviceConnectionHelper.ts b/src/configure/helper/devOps/serviceConnectionHelper.ts deleted file mode 100644 index 757573c4..00000000 --- a/src/configure/helper/devOps/serviceConnectionHelper.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from 'util'; -import { AzureDevOpsClient } from '../../clients/devOps/azureDevOpsClient'; -import { ServiceConnectionClient } from '../../clients/devOps/serviceConnectionClient'; -import { AadApplication } from '../../model/models'; -import { Messages } from '../../resources/messages'; - -export class ServiceConnectionHelper { - private serviceConnectionClient: ServiceConnectionClient; - - public constructor(organizationName: string, projectName: string, azureDevOpsClient: AzureDevOpsClient) { - this.serviceConnectionClient = new ServiceConnectionClient(organizationName, projectName, azureDevOpsClient); - } - - public async createGitHubServiceConnection(name: string, gitHubPat: string): Promise { - let response = await this.serviceConnectionClient.createGitHubServiceConnection(name, gitHubPat); - let endpointId: string = response.id; - await this.waitForGitHubEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - - return endpointId; - } - - public async createAzureSPNServiceConnection(name: string, tenantId: string, subscriptionId: string, scope: string, aadApp: AadApplication): Promise { - let response = await this.serviceConnectionClient.createAzureSPNServiceConnection(name, tenantId, subscriptionId, scope, aadApp); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createAzurePublishProfileServiceConnection(name: string, tenantId: string, resourceId: string, publishProfile: string): Promise { - let response = await this.serviceConnectionClient.createAzurePublishProfileServiceConnection(name, tenantId, resourceId, publishProfile); - let endpointId = response.id; - await this.waitForEndpointToBeReady(endpointId); - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createKubeConfigServiceConnection(name: string, kubeConfig: string, apiServerAddress: string): Promise { - let response = await this.serviceConnectionClient.createKubernetesServiceConnectionWithKubeConfig(name, kubeConfig, apiServerAddress); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - public async createContainerRegistryServiceConnection(name: string, registryUrl: string, registryUsername: string, registryPassword?: string): Promise { - let response = await this.serviceConnectionClient.createContainerRegistryServiceConnection(name, registryUrl, registryUsername, registryPassword); - let endpointId = response.id; - await this.serviceConnectionClient.authorizeEndpointForAllPipelines(endpointId) - .then((response) => { - if (response.allPipelines.authorized !== true) { - throw new Error(Messages.couldNotAuthorizeEndpoint); - } - }); - return endpointId; - } - - private async waitForEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let operationStatus = response.operationStatus; - - if (response.isReady) { - break; - } - - if (!(retryCount < 30) || operationStatus.state.toLowerCase() === "failed") { - throw Error(util.format(Messages.unableToCreateAzureServiceConnection, operationStatus.state, operationStatus.statusMessage)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async waitForGitHubEndpointToBeReady(endpointId: string): Promise { - let retryCount = 1; - while (1) { - let response = await this.serviceConnectionClient.getEndpointStatus(endpointId); - let isReady: boolean = response.isReady; - - if (isReady === true) { - break; - } - - if (!(retryCount < 40)) { - throw Error(util.format(Messages.unableToCreateGitHubServiceConnection, isReady)); - } - - await this.sleepForMilliSeconds(2000); - retryCount++; - } - } - - private async sleepForMilliSeconds(timeInMs: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, timeInMs); - }); - } -} diff --git a/src/configure/helper/gitHubHelper.ts b/src/configure/helper/gitHubHelper.ts deleted file mode 100644 index 32112ca7..00000000 --- a/src/configure/helper/gitHubHelper.ts +++ /dev/null @@ -1,43 +0,0 @@ -export class GitHubProvider { - // private gitHubPatToken: string; - private static GitHubUrl = 'https://github.com/'; - private static SSHGitHubUrl = 'git@github.com:'; - - // constructor(gitHubPat: string) { - // this.gitHubPatToken = gitHubPat; - // } - - public static isGitHubUrl(remoteUrl: string): boolean { - return remoteUrl.startsWith(GitHubProvider.GitHubUrl) || remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl); - } - - public static getRepositoryIdFromUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length); - } - - let endCount: number = remoteUrl.indexOf('.git'); - if (endCount < 0) { - endCount = remoteUrl.length; - } - - return remoteUrl.substring(GitHubProvider.GitHubUrl.length, endCount); - } - - public static getFormattedRemoteUrl(remoteUrl: string): string { - // Is SSH based URL - if (remoteUrl.startsWith(GitHubProvider.SSHGitHubUrl)) { - return `https://github.com/${remoteUrl.substring(GitHubProvider.SSHGitHubUrl.length)}`; - } - - return remoteUrl; - } - - public static getFormattedGitHubApiUrlBase(remoteUrl: string): string { - let params: string[] = GitHubProvider.getRepositoryIdFromUrl(remoteUrl).split('/'); - let accountName: string = params[0]; - let repoName: string = params[1]; - return `https://api.github.com/repos/${accountName}/${repoName}`; - } -} diff --git a/src/configure/helper/graphHelper.ts b/src/configure/helper/graphHelper.ts deleted file mode 100644 index a8d529b7..00000000 --- a/src/configure/helper/graphHelper.ts +++ /dev/null @@ -1,229 +0,0 @@ -const uuid = require('uuid/v1'); -import { AuthenticationContext, MemoryCache, TokenResponse } from 'adal-node'; -import { ServiceClientCredentials, TokenCredentials, UrlBasedRequestPrepareOptions } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import * as util from 'util'; -import { RestClient } from '../clients/restClient'; -import { AadApplication, AzureSession, Token } from '../model/models'; -import { Messages } from '../resources/messages'; -import { executeFunctionWithRetry, generateRandomPassword } from './commonHelper'; - -export class GraphHelper { - - public static async createSpnAndAssignRole(session: AzureSession, aadAppName: string, scope: string): Promise { - let graphCredentials = await this.getGraphToken(session); - let tokenCredentials = new TokenCredentials(graphCredentials.accessToken); - let graphClient = new RestClient(tokenCredentials); - let tenantId = session.tenantId; - var aadApp: AadApplication; - - return this.createAadApp(graphClient, aadAppName, tenantId) - .then((aadApplication) => { - aadApp = aadApplication; - return this.createSpn(graphClient, aadApp.appId, tenantId); - }) - .then((spn) => { - aadApp.objectId = spn.objectId; - return this.createRoleAssignment(session.credentials, scope, aadApp.objectId); - }) - .then(() => { - return aadApp; - }) - .catch((error) => { - let errorMessage = ""; - - if (typeof error == "string") { - errorMessage = error; - } - else { - errorMessage = !!error && error.message; - if (!errorMessage && error["odata.error"]) { - if (typeof error["odata.error"]["message"] === "object") { - errorMessage = error["odata.error"]["message"].value; - } - else { - errorMessage = error["odata.error"]["message"]; - } - } - if (!errorMessage) { - try { - errorMessage = JSON.stringify(error); - } - catch (err) { - - } - } - } - throw new Error(errorMessage); - }); - } - - public static generateAadApplicationName(accountName: string, projectName: string): string { - var spnLengthAllowed = 92; - var guid = uuid(); - var projectName = projectName.replace(/[^a-zA-Z0-9_-]/g, ""); - var accountName = accountName.replace(/[^a-zA-Z0-9_-]/g, ""); - var spnName = accountName + "-" + projectName + "-" + guid; - if (spnName.length <= spnLengthAllowed) { - return spnName; - } - - // 2 is subtracted for delimiter '-' - spnLengthAllowed = spnLengthAllowed - guid.length - 2; - if (accountName.length > spnLengthAllowed / 2 && projectName.length > spnLengthAllowed / 2) { - accountName = accountName.substr(0, spnLengthAllowed / 2); - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - else if (accountName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - accountName = accountName.substr(0, spnLengthAllowed - projectName.length); - } - else if (projectName.length > spnLengthAllowed / 2 && accountName.length + projectName.length > spnLengthAllowed) { - projectName = projectName.substr(0, spnLengthAllowed - accountName.length); - } - - return accountName + "-" + projectName + "-" + guid; - } - - public static async getAccessToken(session: AzureSession): Promise { - const token = await this.getRefreshToken(session); - return token.accessToken; - } - - private static contributorRoleId = "b24988ac-6180-42a0-ab88-20f7382dd24c"; - private static retryTimeIntervalInSec = 2; - private static retryCount = 20; - - private static async getGraphToken(session: AzureSession): Promise { - let refreshTokenResponse = await this.getRefreshToken(session); - return this.getResourceTokenFromRefreshToken(session.environment, refreshTokenResponse.refreshToken, session.tenantId, (session.credentials).clientId, session.environment.activeDirectoryGraphResourceId); - } - - private static async getRefreshToken(session: AzureSession): Promise { - return new Promise((resolve, reject) => { - const credentials: any = session.credentials; - const environment = session.environment; - credentials.context.acquireToken(environment.activeDirectoryResourceId, credentials.username, credentials.clientId, function (err: any, result: any) { - if (err) { - reject(err); - } else { - resolve({ - session, - accessToken: result.accessToken, - refreshToken: result.refreshToken - }); - } - }); - }); - } - - private static async getResourceTokenFromRefreshToken(environment: AzureEnvironment, refreshToken: string, tenantId: string, clientId: string, resource: string): Promise { - return new Promise((resolve, reject) => { - const tokenCache = new MemoryCache(); - const context = new AuthenticationContext(`${environment.activeDirectoryEndpointUrl}${tenantId}`, true, tokenCache); - context.acquireTokenWithRefreshToken(refreshToken, clientId, resource, (err, tokenResponse) => { - if (err) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, err.message))); - } else if (tokenResponse.error) { - reject(new Error(util.format(Messages.acquireTokenFromRefreshTokenFailed, tokenResponse.error))); - } else { - resolve(tokenResponse); - } - }); - }); - } - - private static async createAadApp(graphClient: RestClient, name: string, tenantId: string): Promise { - let secret = generateRandomPassword(20); - let startDate = new Date(Date.now()); - - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/applications`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "availableToOtherTenants": false, - "displayName": name, - "homepage": "https://" + name, - "passwordCredentials": [ - { - "startDate": startDate, - "endDate": new Date(startDate.getFullYear() + 1, startDate.getMonth()), - "value": secret - } - ] - }, - deserializationMapper: null, - serializationMapper: null - }) - .then((data) => { - return { - appId: data.appId, - secret: secret - }; - }); - } - - private static async createSpn(graphClient: RestClient, appId: string, tenantId: string): Promise { - let createSpnPromise = () => { - return graphClient.sendRequest({ - url: `https://graph.windows.net/${tenantId}/servicePrincipals`, - queryParameters: { - "api-version": "1.6" - }, - headers: { - "Content-Type": "application/json", - }, - method: "POST", - body: { - "appId": appId, - "accountEnabled": "true" - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - createSpnPromise, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.azureServicePrincipalFailedMessage); - } - - private static async createRoleAssignment(credentials: ServiceClientCredentials, scope: string, objectId: string): Promise { - let restClient = new RestClient(credentials); - let roleDefinitionId = `${scope}/providers/Microsoft.Authorization/roleDefinitions/${this.contributorRoleId}`; - let guid = uuid(); - let roleAssignementFunction = () => { - return restClient.sendRequest({ - url: `https://management.azure.com/${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}`, - queryParameters: { - "api-version": "2015-07-01" - }, - headers: { - "Content-Type": "application/json", - }, - method: "PUT", - body: { - "properties": { - "roleDefinitionId": roleDefinitionId, - "principalId": objectId - } - }, - deserializationMapper: null, - serializationMapper: null - }); - }; - - return executeFunctionWithRetry( - roleAssignementFunction, - GraphHelper.retryCount, - GraphHelper.retryTimeIntervalInSec, - Messages.roleAssignmentFailedMessage); - } -} \ No newline at end of file diff --git a/src/configure/helper/mustacheHelper.ts b/src/configure/helper/mustacheHelper.ts deleted file mode 100644 index ff8def2c..00000000 --- a/src/configure/helper/mustacheHelper.ts +++ /dev/null @@ -1,288 +0,0 @@ -import * as Mustache from 'mustache'; -import * as Semver from 'semver'; - -export class MustacheHelper { - public static getHelperMethods(): any { - return { - - "equals": function () { - /* - * Usage: {{#equals}}value1 value2 true/false(ignorecase) returnIfTrue returnIfFalse(optional){{/regexReplace}} - * {{#equals}}{{{inputs.Input1}}} value1 true value1 'input 1 has invalid input'{{/regexReplace}} - */ - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase() === parts[1].toLowerCase()) { - return parts[3]; - } - } else { - if (parts[0] === parts[1]) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - "if": function () { - /* - * if returns first parameter if given clause is positive, otherwise second parameter - * Usage: {{#if}}clause trueValue falseValue{{/if}} - */ - return function (text: string, render: any) { - let parts = MustacheHelper.getParts(text); - if (parts.length > 1) { - if (render(parts[0]) === "true") { - return render(parts[1]); - } - else { - if (parts[2]) { - return render(parts[2]); - } - - return ""; - } - } - }; - }, - - "toLower": function () { - /* - * converts the string to lower case - * Usage: {{#toLower}} String to convert to lower case {{/toLower}} - */ - return function (text: string, render: any) { - return render(text).toLowerCase(); - }; - }, - - "tinyguid": function () { - /* - * Generates 4 character random string - * Usage: {{#tinyguid}} {{/tinyguid}} - */ - return function () { - return "yxxx".replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0; - var v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - }, - - "sanitizeString": function () { - /* - * Converts string to alphanumeric - * Usage: {{#sanitizeString}} String to convert to alphanumeric {{/sanitizeString}} - */ - return function (text: string, render: any) { - return render(text).replace(/[^a-zA-Z0-9]/g, ''); - }; - }, - - "substring": function () { - /* - * Trims given string to specified length - * Usage: {{#substring}}'text' from length{{/substring}} - * from, length are integers - */ - return function (text: string, render: any) { - var renderedText = render(text); - var parts = MustacheHelper.getParts(renderedText); - - if (parts.length < 3) { - return render(""); - } - else { - var start = +parts[1]; - var length = +parts[2]; - return render(parts[0].substr(start, length)); - } - }; - }, - - "parseAzureResourceId": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length !== 2) { - return ""; - } - - var splitResourceId = parts[0].split("/"); - var urlResourcePartIndex = parseInt(parts[1]); - if (splitResourceId && urlResourcePartIndex && splitResourceId.length > urlResourcePartIndex) { - return splitResourceId[urlResourcePartIndex]; - } - - return ""; - }; - }, - - /* - * Checks if a string begins with some string - * Usage: {{#beginsWith}} StringToCheck BeginningPart true/false(for case-sensitivity) IfTrueValue IfFalseValue(optional){{/beginsWith}} - */ - "beginsWith": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 4) { - return ""; - } - - var ignoreCase = parts[2]; - if (ignoreCase) { - if (parts[0].toLowerCase().startsWith(parts[1].toLowerCase())) { - return parts[3]; - } - } else { - if (parts[0].startsWith(parts[1])) { - return parts[3]; - } - } - if (parts.length >= 5) { - return parts[4]; - } else { - return ""; - } - }; - }, - - /* - * If some variable is the environment variable, adding {{ }} - * Usage: {{#EnvironmentVariable}} VariableName {{/EnvironmentVariable}} - */ - "environmentVariable": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length < 1) { - return ""; - } - return "{{ " + parts[0] + " }}"; - }; - }, - - /* - * Sort an integer array - * Usage: {{#intSorter}} IntegerArrayToBeSorted asc/dsc(order in which it is to be sorted) {{/intSorter}} - */ - "intSorter": function () { - return function (text: string, render: any) { - var parts = MustacheHelper.getParts(text); - if (parts.length < 2) { - return ""; - } - - var order = parts[1].toLowerCase(); - var arr = render(parts[0]).split(","); - var sorter = 1; - if (order === "dsc") { - sorter = -1; - } - arr = arr.sort((a, b) => { - if (a > b) { return 1 * sorter; } - else { return -1 * sorter; } - }); - return arr; - }; - }, - - /* - * Replaces substring of the main string with new value - * Usage: {{#stringReplace}} OldString Old New {{/stringReplace}} -> 'NewString' - */ - "stringReplace": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 3) { - return ""; - } - return parts[0].replace(parts[1], parts[2]); - } - }, - - /* - * Evaluates if the semver condition is satified and return output accordingly - * Usage: {{#semverSatisfy}} 'given.version' 'condition' {{/semverSatisfy}} - */ - - "semverSatisfy": function () { - return function (text: string, render: any) { - var renderedText: string = render(text); - var parts = MustacheHelper.getParts(renderedText); - if (parts.length != 4) { - return ""; - } - var givenVersion = parts[0].trim(); - var semverCondition = parts[1].trim(); - if (givenVersion.length == 0 || semverCondition.length == 0) - return parts[3]; - givenVersion = Semver.minVersion(givenVersion); - if (Semver.satisfies(givenVersion, semverCondition)) - return parts[2]; - return parts[3]; - } - } - }; - } - - public static render(mustacheExpression: string, view: any): string { - view = { ...this.getHelperMethods(), ...view }; - return Mustache.render(mustacheExpression, view); - } - - public static renderObject(mustacheObject: Object, view: any): any { - if (typeof (mustacheObject) === "string") { - return MustacheHelper.render(mustacheObject, view); - } - - var resultArray: any[] = []; - if (Array.isArray(mustacheObject)) { - mustacheObject.forEach(item => { - resultArray.push(MustacheHelper.renderObject(item, view)); - }); - return resultArray; - } - - var result: Object = {}; - if (mustacheObject) { - Object.keys(mustacheObject).forEach(key => { - if (!!key && !!mustacheObject[key]) { - result[key] = MustacheHelper.renderObject(mustacheObject[key], view); - } - }); - - } - return result; - } - - public static getParts(text: string): Array { - var parts: Array = []; - /* Following regex is to fetch different parts in the text e.g. "test 'hello world' output" => test, 'hello world', output*/ - var fetchPartsRegex = new RegExp(/[\'](.*?)[\']|[^ ]+/g); - var resultArray; - while ((resultArray = fetchPartsRegex.exec(text)) !== null) { - var part = (resultArray[1] === undefined || resultArray[1] === null) ? resultArray[0] : resultArray[1]; - if (part === "''") { - part = ""; - } - parts.push(part); - } - - return parts; - } -} diff --git a/src/configure/helper/remoteServiceUrlHelper.ts b/src/configure/helper/remoteServiceUrlHelper.ts deleted file mode 100644 index a581595f..00000000 --- a/src/configure/helper/remoteServiceUrlHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { RestClient } from "typed-rest-client"; -import { TracePoints } from "../resources/tracePoints"; -import { telemetryHelper } from "./telemetryHelper"; - -export enum ServiceFramework { - Moda, - Vssf -} - -export interface IServiceUrlDefinition { - serviceFramework: ServiceFramework; - serviceUrl: string; -} - -export class RemoteServiceUrlHelper { - public static repoAnalysisRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2127646"; - public static templateServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2133849"; - public static provisioningServiceRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2142042"; - public static repoAnalysisStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156682"; - public static templateServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156978"; - public static provisioningServiceStagingRedirectUrl: string = "https://go.microsoft.com/fwlink/?linkid=2156977"; - - public static async getTemplateServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.templateServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.templateServiceRedirectUrl); - } - - public static async getRepositoryAnalysisDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.repoAnalysisStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.repoAnalysisRedirectUrl); - } - - public static async getProvisioningServiceDefinition(): Promise { - const deployment = process.env["DEPLOY_TO_AZURE_EXT_ENVIRONMENT"]; - if (deployment != undefined && deployment === "development") { - return { - serviceFramework: ServiceFramework.Moda, - serviceUrl: process.env["PROXY_URL"] + "repos/" - } as IServiceUrlDefinition; - } - - if (deployment != undefined && deployment === "staging") { - return this.getServiceurlDefinition(this.provisioningServiceStagingRedirectUrl); - } - - return this.getServiceurlDefinition(this.provisioningServiceRedirectUrl); - } - - private static async getServiceurlDefinition(redirectUrl: string) { - const result = { - serviceFramework: ServiceFramework.Vssf - }; - try { - const requestOptions = { - allowRedirects: false - }; - const restClient = new RestClient("deploy-to-azure", "", [], requestOptions); - const response = await restClient.client.get(redirectUrl, requestOptions); - if ((response.message.statusCode === 301 || response.message.statusCode === 302)) { - result.serviceUrl = response.message.headers["location"]; - } else { - throw Error("Invalid response from url " + redirectUrl); - } - if (!result.serviceUrl.includes("portalext.visualstudio.com")) { - result.serviceFramework = ServiceFramework.Moda; - } - } catch (error) { - telemetryHelper.logError('configure', TracePoints.RemoteServiceUrlFetchFailed, error); - } - return result; - - } -} diff --git a/src/configure/helper/repoAnalysisHelper.ts b/src/configure/helper/repoAnalysisHelper.ts deleted file mode 100644 index 1a9723a8..00000000 --- a/src/configure/helper/repoAnalysisHelper.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { ApplicationSettings, CodeRepository, RepositoryAnalysis, SourceRepository } from "azureintegration-repoanalysis-client-internal"; -import * as path from 'path'; -import { ModaRepositoryAnalysisClient } from '../clients/modaRepositoryAnalysisClient'; -import { PortalExtensionRepositoryAnalysisClient } from "../clients/portalExtensionRepositoryAnalysisClient"; -import { IRepositoryAnalysisClient } from '../clients/repositoryAnalyisClient'; -import { AzureSession, GitRepositoryParameters, RepositoryProvider, SupportedLanguage } from "../model/models"; -import { RepoAnalysisConstants } from "../resources/constants"; -import { TracePoints } from "../resources/tracePoints"; -import { IServiceUrlDefinition, RemoteServiceUrlHelper, ServiceFramework } from './remoteServiceUrlHelper'; -import { telemetryHelper } from "./telemetryHelper"; - -const Layer: string = 'repoAnalysisHelper'; -export class RepoAnalysisHelper { - private azureSession: AzureSession; - private githubPatToken?: string; - constructor(azureSession: AzureSession, githubPatToken?: string) { - this.azureSession = azureSession; - this.githubPatToken = githubPatToken; - } - - public async getRepositoryAnalysis(sourceRepositoryDetails: GitRepositoryParameters, workspacePath: string): Promise { - - let repositoryAnalysisResponse; - try { - const serviceDefinition = await RemoteServiceUrlHelper.getRepositoryAnalysisDefinition(); - const client = this.getClient(serviceDefinition); - - const repositoryDetails: CodeRepository = {} as CodeRepository; - repositoryDetails.id = sourceRepositoryDetails.repositoryId; - repositoryDetails.defaultBranch = !!sourceRepositoryDetails.branch ? sourceRepositoryDetails.branch : RepoAnalysisConstants.Master; - repositoryDetails.type = RepositoryProvider.Github; - - let repositoryAnalysisRequestBody = {} as SourceRepository; - repositoryAnalysisRequestBody.repository = repositoryDetails; - repositoryAnalysisRequestBody.workingDirectory = workspacePath; - repositoryAnalysisRequestBody.repository.authorizationInfo = { - scheme: "Token", - parameters: { - accesstoken: this.githubPatToken - } - }; - repositoryAnalysisResponse = await client.getRepositoryAnalysis(repositoryAnalysisRequestBody); - if (!!repositoryAnalysisResponse && repositoryAnalysisResponse.length === 0) { - return null; - } - } - catch (e) { - //Return empty if Repo Analysis fails - telemetryHelper.logError(Layer, TracePoints.RepoAnalysisFailed, e); - return null; - } - - let parameters: RepositoryAnalysis = {} as RepositoryAnalysis; - parameters.applicationSettingsList = []; - repositoryAnalysisResponse.applicationSettingsList.forEach((analysis) => { - - //Process only for VSCode Supported Languages - if (Object.keys(SupportedLanguage).indexOf(analysis.language.toUpperCase()) > -1) { - let applicationSettings: ApplicationSettings = {} as ApplicationSettings; - applicationSettings.language = analysis.language; - - if (!!analysis.settings) { - if (!!analysis.settings.workingDirectory) { - if (!applicationSettings.settings) { - applicationSettings.settings = {}; - } - applicationSettings.settings.workingDirectory = analysis.settings.workingDirectory.split('\\').join('/'); - } - if (!!analysis.buildTargetName) { - applicationSettings.buildTargetName = analysis.buildTargetName; - if (analysis.language === SupportedLanguage.NODE) { - applicationSettings.settings[RepoAnalysisConstants.PackageFilePath] = analysis.settings[RepoAnalysisConstants.PackageFilePath]; - applicationSettings.settings.packageFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.PackageFilePath]); - if (analysis.buildTargetName === RepoAnalysisConstants.Gulp && !!analysis.settings[RepoAnalysisConstants.GulpFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GulpFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GulpFilePath]); - } - else if (analysis.buildTargetName === RepoAnalysisConstants.Grunt && !!analysis.settings[RepoAnalysisConstants.GruntFilePath]) { - applicationSettings.settings[RepoAnalysisConstants.GruntFilePath] = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.GruntFilePath]); - } - } - else if (analysis.language === SupportedLanguage.PYTHON) { - if (!!analysis.settings[RepoAnalysisConstants.RequirementsFilePath]) { - applicationSettings.settings.pythonRequirementsFilePath = this.GetRelativePath( - applicationSettings.settings.workingDirectory, analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - applicationSettings.settings.pythonRequirementsFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.RequirementsFilePath]); - } - } else { - applicationSettings.settings = analysis.settings; - applicationSettings.settings.workingDirectory = applicationSettings.settings.workingDirectory.split('\\').join('/'); - } - } - if (!!analysis.deployTargetName) { - applicationSettings.deployTargetName = analysis.deployTargetName; - if (analysis.deployTargetName === RepoAnalysisConstants.AzureFunctions) { - applicationSettings.settings.azureFunctionsHostFilePath = analysis.settings[RepoAnalysisConstants.HostFilePath]; - applicationSettings.settings.azureFunctionsHostFileDirectory = path.dirname(analysis.settings[RepoAnalysisConstants.HostFilePath]); - } - } - - } - parameters.applicationSettingsList.push(applicationSettings); - } - }); - return parameters; - } - - private GetRelativePath(workingDirectory: string, filePath: string): string { - return path.relative(workingDirectory, filePath).split(path.sep).join('/'); - } - - private getClient(serviceDefinition: IServiceUrlDefinition): IRepositoryAnalysisClient { - let client = null; - if (serviceDefinition.serviceFramework === ServiceFramework.Vssf) { - client = new PortalExtensionRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.azureSession.credentials); - } else { - client = new ModaRepositoryAnalysisClient(serviceDefinition.serviceUrl, this.githubPatToken); - } - return client; - } -} diff --git a/src/configure/helper/sodium/SodiumLibHelper.ts b/src/configure/helper/sodium/SodiumLibHelper.ts deleted file mode 100644 index 2c1d2beb..00000000 --- a/src/configure/helper/sodium/SodiumLibHelper.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as sodium from 'tweetsodium'; - -export class SodiumLibHelper { - key: Uint8Array; - - constructor(key: Uint8Array | string) { - if (typeof (key) == "string") { - let decodedKey = SodiumLibHelper.decodeFromBase64(key); - this.key = SodiumLibHelper.convertStringToUint8Array(decodedKey); - } else { - this.key = key; - } - } - - public encrypt (message: Uint8Array | string) { - if (typeof (message) == "string") { - return sodium.seal(SodiumLibHelper.convertStringToUint8Array(message), this.key) - } else { - return sodium.seal(message, this.key) - } - } - - public static decodeFromBase64(encoded: string): string { - let decodedbase64 = new Buffer(encoded, 'base64'); - return decodedbase64.toString('binary') - } - - public static encodeToBase64 (decoded: string): string { - return (new Buffer(decoded, 'binary')).toString('base64') - } - - public static convertStringToUint8Array (v: string): Uint8Array { - let body = v.split('') - let _body = body.map((a) => { - return a.charCodeAt(0); - }) - return Uint8Array.from(_body) - } - - public static convertUint8ArrayToString (bytes: Uint8Array): string { - return String.fromCharCode.apply(null, Array.from(bytes)) - } -} - diff --git a/src/configure/helper/sodium/sodium.d.ts b/src/configure/helper/sodium/sodium.d.ts deleted file mode 100644 index c691b6e1..00000000 --- a/src/configure/helper/sodium/sodium.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "tweetsodium" { - export function seal(messageBytes: Uint8Array, keyBytes: Uint8Array) : any -} \ No newline at end of file diff --git a/src/configure/helper/telemetryHelper.ts b/src/configure/helper/telemetryHelper.ts deleted file mode 100644 index d35772a4..00000000 --- a/src/configure/helper/telemetryHelper.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { IActionContext, ITelemetryReporter, parseError } from "vscode-azureextensionui"; - -import * as logger from '../../logger'; -import { extensionVariables } from "../model/models"; -import { TelemetryKeys } from '../resources/telemetryKeys'; - -const uuid = require('uuid/v4'); - -class TelemetryHelper { - private actionContext: IActionContext; - private telemetryReporter: ITelemetryReporter; - private journeyId: string; - private command: string; - - public initialize(actionContext: IActionContext, command: string): void { - this.actionContext = actionContext; - this.telemetryReporter = extensionVariables.reporter; - this.journeyId = uuid(); - this.command = command; - this.setTelemetry(TelemetryKeys.JourneyId, this.journeyId); - } - - public getJourneyId(): string { - return this.journeyId; - } - - public setTelemetry(key: string, value: string): void { - if (key) { - this.actionContext.telemetry.properties[key] = value; - } - } - - public setResult(result: Result, error?: Error): void { - this.actionContext.telemetry.properties.result = result; - if (error) { - let parsedError = parseError(error); - this.actionContext.telemetry.properties.error = JSON.stringify(parsedError); - this.actionContext.telemetry.properties.errorMessage = parsedError.message; - } - } - - public setCurrentStep(stepName: string): void { - //current step is the last step till which user reaches - this.actionContext.telemetry.properties["currentStep"] = stepName; - } - - public logError(layer: string, tracePoint: string, error: Error): void { - let parsedError = parseError(error); - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'error': JSON.stringify(parsedError) - }); - - logger.log(JSON.stringify(parsedError)); - } - - public logInfo(layer: string, tracePoint: string, info: string): void { - this.telemetryReporter.sendTelemetryEvent( - tracePoint, - { - 'journeyId': this.journeyId, - 'command': this.command, - 'layer': layer, - 'info': info - }); - } - - public async executeFunctionWithTimeTelemetry(callback: () => T, telemetryKey: string): Promise { - let startTime = Date.now(); - try { - return await callback(); - } - finally { - this.setTelemetry(telemetryKey, ((Date.now() - startTime) / 1000).toString()); - } - } -} -export let telemetryHelper = new TelemetryHelper(); - -export enum Result { - 'Succeeded' = 'Succeeded', - 'Failed' = 'Failed', - 'Canceled' = 'Canceled' -} diff --git a/src/configure/helper/templateHelper.ts b/src/configure/helper/templateHelper.ts deleted file mode 100644 index 3b31d50c..00000000 --- a/src/configure/helper/templateHelper.ts +++ /dev/null @@ -1,1509 +0,0 @@ -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { RepositoryAnalysis } from 'azureintegration-repoanalysis-client-internal'; -import * as fs from 'fs'; -import * as Mustache from 'mustache'; -import * as path from 'path'; -import * as Q from 'q'; -import { TemplateServiceClientFactory } from '../clients/TemplateServiceClientFactory'; -import { ExtendedPipelineTemplate } from '../model/Contracts'; -import { AzureConnectionType, AzureSession, extensionVariables, GitRepositoryParameters, MustacheContext, PipelineType, RepositoryProvider, SupportedLanguage, TargetKind, TargetResourceType } from '../model/models'; -import { LocalPipelineTemplate, PipelineTemplate, PreDefinedDataSourceIds, RemotePipelineTemplate, TemplateAssetType, TemplateInfo, TemplateParameterType, TemplateType } from '../model/templateModels'; -import { PipelineTemplateLabels, RepoAnalysisConstants } from '../resources/constants'; -import { Messages } from '../resources/messages'; -import { TelemetryKeys } from '../resources/telemetryKeys'; -import { TracePoints } from '../resources/tracePoints'; -import { MustacheHelper } from './mustacheHelper'; -import { telemetryHelper } from './telemetryHelper'; - -const Layer: string = 'templateHelper'; -export async function mergingRepoAnalysisResults(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis): Promise { - let localRepoAnalysisResult = await analyzeRepo(sourceRepository.localPath); - let analysisResult = localRepoAnalysisResult; - - //If Repo analysis fails then we'll go with the basic existing analysis - if (sourceRepository.repositoryProvider === RepositoryProvider.Github && !!repoAnalysisParameters && !!repoAnalysisParameters.applicationSettingsList) { - analysisResult = new AnalysisResult(); - repoAnalysisParameters.applicationSettingsList.forEach((settings) => { - analysisResult.languages.push(settings.language as SupportedLanguage); - - //Check if Azure:Functions is value of any deployTargetName property - analysisResult.isFunctionApp = - analysisResult.isFunctionApp || settings.deployTargetName === RepoAnalysisConstants.AzureFunctions ? true : false; - }); - - //Languages not supported by RepoAnalysisService should be considered and taken from LocalRepoAnalysis - localRepoAnalysisResult.languages.forEach((language) => { - if (analysisResult.languages.indexOf(language) === -1) { - analysisResult.languages.push(language); - } - }); - - if (analysisResult.languages.length === 0) { - analysisResult.languages.push(SupportedLanguage.NONE); - } - } - return analysisResult; -} - -export function getTargetType(template: TemplateInfo): TargetResourceType { - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - return TargetResourceType.WebApp; - } else if (template.attributes.deployTarget === "Azure:AKS") { - return TargetResourceType.AKS; - } - return TargetResourceType.None; -} - -export function getTargetKind(template: TemplateInfo): TargetKind { - var targetKind: TargetKind; - if (template.attributes.deployTarget.toLowerCase().includes("webapp")) { - if (template.attributes.deployTarget.toLowerCase().includes("container")) { - targetKind = TargetKind.LinuxContainerApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("linux")) { - targetKind = TargetKind.LinuxApp; - } else if (template.attributes.deployTarget.toLowerCase().includes("windows")) { - targetKind = TargetKind.WindowsApp; - } - } - else { - targetKind = null; - } - return targetKind; -} - -export function uniqueValues(value, index, self) { - return self.indexOf(value) === index; -} - -export async function analyzeRepoAndListAppropriatePipeline(sourceRepository: GitRepositoryParameters, repoAnalysisParameters: RepositoryAnalysis, targetResource?: GenericResource): Promise { - - let analysisResult = await mergingRepoAnalysisResults(sourceRepository, repoAnalysisParameters); - - let templateList: { [key: string]: LocalPipelineTemplate[] } = {}; - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateList = azurePipelineTemplates; - break; - case RepositoryProvider.Github: - templateList = extensionVariables.enableGitHubWorkflow ? githubWorklowTemplates : azurePipelineTemplates; - break; - default: - throw new Error(Messages.cannotIdentifyRespositoryDetails); - } - - - let templateResult: LocalPipelineTemplate[] = []; - let uniqueLanguages = (analysisResult.languages).filter(this.uniqueValues); - - uniqueLanguages.forEach((language) => { - switch (language) { - case SupportedLanguage.DOCKER: - if (templateList[SupportedLanguage.DOCKER] && templateList[SupportedLanguage.DOCKER].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOCKER]); - } - break; - case SupportedLanguage.NODE: - if (templateList[SupportedLanguage.NODE] && templateList[SupportedLanguage.NODE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NODE]); - } - break; - case SupportedLanguage.PYTHON: - if (templateList[SupportedLanguage.PYTHON] && templateList[SupportedLanguage.PYTHON].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.PYTHON]); - } - break; - case SupportedLanguage.DOTNETCORE: - if (templateList[SupportedLanguage.DOTNETCORE] && templateList[SupportedLanguage.DOTNETCORE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.DOTNETCORE]); - } - break; - case SupportedLanguage.NONE: - if (templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateResult.concat(templateList[SupportedLanguage.NONE]); - } - break; - default: - break; - } - }); - - if (templateResult.length < 1 && templateList[SupportedLanguage.NONE] && templateList[SupportedLanguage.NONE].length > 0) { - templateResult = templateList[SupportedLanguage.NONE]; - } - - if (analysisResult.isFunctionApp) { - switch (sourceRepository.repositoryProvider) { - case RepositoryProvider.AzureRepos: - templateResult = azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - case RepositoryProvider.Github: - templateResult = extensionVariables.enableGitHubWorkflow ? githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult) : azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp].concat(templateResult); - break; - default: - break; - } - } - - templateResult = targetResource && !!targetResource.type ? templateResult.filter((template) => !template.targetType || template.targetType.toLowerCase() === targetResource.type.toLowerCase()) : templateResult; - templateResult = targetResource && !!targetResource.kind ? templateResult.filter((template) => !template.targetKind || template.targetKind.toLowerCase() === targetResource.kind.toLowerCase()) : templateResult; - templateResult = templateResult.filter((pipelineTemplate) => pipelineTemplate.enabled); - - return templateResult; -} - -async function convertToPipelineTemplate(remoteTemplates: TemplateInfo[]): Promise { - const pipelineTemplates: PipelineTemplate[] = []; - if (!!remoteTemplates) { - remoteTemplates.forEach((templateInfo: TemplateInfo) => { - const remoteTemplate: RemotePipelineTemplate = { - label: templateInfo.templateLabel, - targetType: getTargetType(templateInfo), - targetKind: getTargetKind(templateInfo), - templateType: TemplateType.REMOTE, - language: templateInfo.attributes.language, - id: templateInfo.templateId, - templateWeight: templateInfo.templateWeight, - workingDirectory: templateInfo.workingDirectory, - description: templateInfo.templateDescription, - }; - pipelineTemplates.push(remoteTemplate); - }); - } - return pipelineTemplates; -} - -export async function getFilteredTemplates(resourceType: string): Promise { - - const client = await TemplateServiceClientFactory.getClient(); - let filteredTemplates: TemplateInfo[]; - switch (resourceType) { - case TargetResourceType.AKS: - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - filteredTemplates = await client.getTemplatesInfoByFilter("docker", "Azure:AKS"); - }, TelemetryKeys.TemplateServiceDuration); - return filteredTemplates; - default: - return null; - } -} - -export async function getTemplates(repoAnalysisParameters: RepositoryAnalysis) { - const client = await TemplateServiceClientFactory.getClient(); - let templates: TemplateInfo[]; - await telemetryHelper.executeFunctionWithTimeTelemetry(async () => { - templates = await client.getTemplates(repoAnalysisParameters); - }, TelemetryKeys.TemplateServiceDuration); - return templates; -} - -export async function analyzeRepoAndListAppropriatePipeline2(azureSession: AzureSession, sourceRepository: GitRepositoryParameters, pipelineType: PipelineType, repoAnalysisParameters: RepositoryAnalysis, githubPatToken?: string, resource?: GenericResource): Promise { - - let pipelineTemplates: PipelineTemplate[] = []; - let remoteTemplates: TemplateInfo[] = []; - let localPipelineTemplates: LocalPipelineTemplate[] = await this.analyzeRepoAndListAppropriatePipeline(sourceRepository, repoAnalysisParameters); - - if (pipelineType === PipelineType.GitHubPipeline) { - try { - if (!!resource) { - localPipelineTemplates = []; - remoteTemplates = await getFilteredTemplates(resource.type); - } - else if (repoAnalysisParameters && repoAnalysisParameters.applicationSettingsList) { - remoteTemplates = await getTemplates(repoAnalysisParameters); - } - pipelineTemplates = await convertToPipelineTemplate(remoteTemplates); - pipelineTemplates = pipelineTemplates.concat(localPipelineTemplates); - // sorted by weight - pipelineTemplates = pipelineTemplates.sort((a, b) => { - return b.templateWeight - a.templateWeight; - }); - return pipelineTemplates; - } - catch (err) { - pipelineTemplates = []; - telemetryHelper.logError(Layer, TracePoints.TemplateServiceCallFailed, err); - return null; - } - } - else { - return localPipelineTemplates; - } -} - -export async function getTemplateParameters(templateId: string): Promise { - let parameters: ExtendedPipelineTemplate; - try { - let serviceClient = await TemplateServiceClientFactory.getClient(); - parameters = await serviceClient.getTemplateParameters(templateId); - return parameters; - } - catch (e) { - telemetryHelper.logError(Layer, TracePoints.UnableToGetTemplateParameters, e); - throw new Error(Messages.UnableToGetTemplateParameters); - } - -} - -export function getPipelineTemplatesForAllWebAppKind(repositoryProvider: RepositoryProvider, label: string, language: string, targetKind: TargetKind): LocalPipelineTemplate[] { - let pipelineTemplates: LocalPipelineTemplate[] = []; - - if (repositoryProvider === RepositoryProvider.Github && extensionVariables.enableGitHubWorkflow) { - pipelineTemplates = githubWorklowTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(githubWorkflowTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - else { - pipelineTemplates = azurePipelineTemplates[language]; - if (isFunctionAppType(targetKind)) { - pipelineTemplates = pipelineTemplates.concat(azurePipelineTargetBasedTemplates[AzureTarget.FunctionApp]); - } - } - - return pipelineTemplates.filter((template) => { - return template.label.toLowerCase() === label.toLowerCase() && template.targetType === TargetResourceType.WebApp && template.language === language; - }); -} - -export async function renderContent(templateFilePath: string, context: MustacheContext): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readFile(templateFilePath, { encoding: "utf8" }, async (error, data) => { - if (error) { - throw new Error(error.message); - } - else { - let updatedContext: MustacheContext; - updatedContext = { ...MustacheHelper.getHelperMethods(), ...context }; - let fileContent = Mustache.render(data, updatedContext); - deferred.resolve(fileContent); - } - }); - - return deferred.promise; -} - -export function getDockerPort(repoPath: string, relativeDockerFilePath?: string): string { - let dockerfilePath = relativeDockerFilePath; - if (!dockerfilePath) { - let files = fs.readdirSync(repoPath); - files.some((fileName) => { if (fileName.toLowerCase().endsWith('dockerfile')) { dockerfilePath = fileName; return true; } return false; }); - if (!dockerfilePath) { - return null; - } - } - - try { - let dockerContent = fs.readFileSync(path.join(repoPath, dockerfilePath), 'utf8'); - let index = dockerContent.toLowerCase().indexOf('expose '); - if (index !== -1) { - let temp = dockerContent.substring(index + 'expose '.length); - let ports = temp.substr(0, temp.indexOf('\n')).split(' ').filter(Boolean); - if (ports.length) { - return ports[0]; - } - } - return null; - } - catch (err) { - telemetryHelper.logError(Layer, TracePoints.ReadingDockerFileFailed, err); - } - - return null; -} - -async function analyzeRepo(repoPath: string): Promise { - let deferred: Q.Deferred = Q.defer(); - fs.readdir(repoPath, (err, files: string[]) => { - let result: AnalysisResult = new AnalysisResult(); - result.languages = []; - result.languages = isDockerApp(files) ? result.languages.concat(SupportedLanguage.DOCKER) : result.languages; - result.languages = isNodeRepo(files) ? result.languages.concat(SupportedLanguage.NODE) : result.languages; - result.languages = isPythonRepo(files) ? result.languages.concat(SupportedLanguage.PYTHON) : result.languages; - result.languages = isDotnetCoreRepo(files) ? result.languages.concat(SupportedLanguage.DOTNETCORE) : result.languages; - - result.isFunctionApp = err ? true : isFunctionApp(files), - - deferred.resolve(result); - }); - - return deferred.promise; -} - -function isDotnetCoreRepo(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("sln") || file.toLowerCase().endsWith("csproj") || file.toLowerCase().endsWith("fsproj"); - }); -} - -function isNodeRepo(files: string[]): boolean { - let nodeFilesRegex = '\\.ts$|\\.js$|package\\.json$|node_modules'; - return files.some((file) => { - let result = new RegExp(nodeFilesRegex).test(file.toLowerCase()); - return result; - }); -} - -function isPythonRepo(files: string[]): boolean { - let pythonRegex = '.py$'; - return files.some((file) => { - let result = new RegExp(pythonRegex).test(file.toLowerCase()); - return result; - }); -} - -function isDockerApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("dockerfile"); - }); -} - -function isFunctionApp(files: string[]): boolean { - return files.some((file) => { - return file.toLowerCase().endsWith("host.json"); - }); -} - -export function isFunctionAppType(targetKind: TargetKind): boolean { - return targetKind === TargetKind.FunctionApp || targetKind === TargetKind.FunctionAppLinux || targetKind === TargetKind.FunctionAppLinuxContainer; -} - -export class AnalysisResult { - public languages: SupportedLanguage[] = []; - public isFunctionApp: boolean = false; - // public isContainerized: boolean; -} - -export enum AzureTarget { - FunctionApp = 'Microsoft.Web/sites-functionapp' -} - -let azurePipelineTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = -{ - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL, - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejs.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngular.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: 'Build and Test Python Django App', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonDjango.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.None, - targetKind: null, - enabled: true, - parameters: [], - azureConnectionType: AzureConnectionType.None, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnetcore': [ - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreWebAppToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: false, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": '80' - } - ], - assets: [ - { - "id": "kubernetesServiceConnection ", - "type": TemplateAssetType.AKSKubeConfigServiceConnection - }, - { - "id": "containerRegistryServiceConnection", - "type": TemplateAssetType.ACRServiceConnection - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'dotnet': [] -}; - -let githubWorklowTemplates: { [key in SupportedLanguage]: LocalPipelineTemplate[] } = { - 'docker': [ - { - label: 'Containerized application to AKS', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml'), - language: SupportedLanguage.DOCKER, - targetType: TargetResourceType.AKS, - targetKind: null, - enabled: true, - parameters: [ - { - "name": "aksCluster", - "displayName": "Select Azure Kubernetes cluster to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.AKS - }, - { - "name": "containerRegistry", - "displayName": "Select Azure Container Registry to store docker image", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.ACR - }, - { - "name": "containerPort", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": PreDefinedDataSourceIds.RepoAnalysis, - "defaultValue": "80" - }, - { - "name": "namespace", - "displayName": null, - "type": TemplateParameterType.String, - "dataSourceId": "", - "defaultValue": "{{#toLower}}{{#sanitizeString}}{{{inputs.aksCluster.name}}}{{/sanitizeString}}{{/toLower}}{{#tinyguid}}{{/tinyguid}}" - } - ], - assets: [ - { - "id": "kubeConfig", - "type": TemplateAssetType.GitHubAKSKubeConfig - }, - { - "id": "containerRegistryUsername", - "type": TemplateAssetType.GitHubRegistryUsername - }, - { - "id": "containerRegistryPassword", - "type": TemplateAssetType.GitHubRegistryPassword - }, - { - "id": "deployment", - "type": TemplateAssetType.File - }, - { - "id": "service", - "type": TemplateAssetType.File - }, - { - "id": "ingress", - "type": TemplateAssetType.File - }, - { - "id": "service-ingress", - "type": TemplateAssetType.File - } - ], - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'node': [ - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithNpmToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGulpToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithGruntToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithAngularToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSWithWebpackToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'none': [ - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.WindowsApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.WindowsApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMPublishProfileServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMPublishProfile, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.SimpleApplicationToAppService, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/simpleWebApp.yml'), - language: SupportedLanguage.NONE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ], - 'python': [ - { - label: 'Python to Linux Web App on Azure', - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.LinuxApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure webapp to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ], - 'dotnetcore': [], - 'dotnet': [] -}; - -const azurePipelineTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: false, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.DotNetCoreFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml'), - language: SupportedLanguage.DOTNETCORE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - ] -}; - -const githubWorkflowTargetBasedTemplates: { [key in AzureTarget]: LocalPipelineTemplate[] } = -{ - 'Microsoft.Web/sites-functionapp': [ - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionApp, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.FunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - //To-DO : weight is greater than the remote templates, to be changed later - templateWeight: 999999, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.NodeJSFunctionAppToAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml'), - language: SupportedLanguage.NODE, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinux, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - }, - { - label: PipelineTemplateLabels.PythonFunctionAppToLinuxAzureFunction, - path: path.join(path.dirname(path.dirname(__dirname)), 'configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml'), - language: SupportedLanguage.PYTHON, - targetType: TargetResourceType.WebApp, - targetKind: TargetKind.FunctionAppLinuxContainer, - enabled: true, - parameters: [ - { - "name": "webapp", - "displayName": "Select the target Azure Function to deploy your application", - "type": TemplateParameterType.GenericAzureResource, - "dataSourceId": PreDefinedDataSourceIds.LinuxContainerFunctionApp - } - ], - assets: [ - { - "id": "endpoint", - "type": TemplateAssetType.AzureARMServiceConnection - } - ], - azureConnectionType: AzureConnectionType.AzureRMServicePrincipal, - templateWeight: 100, - templateType: TemplateType.LOCAL - } - ] -}; diff --git a/src/configure/helper/templateParameterHelper.ts b/src/configure/helper/templateParameterHelper.ts deleted file mode 100644 index 35c974fb..00000000 --- a/src/configure/helper/templateParameterHelper.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { GenericResource } from "azure-arm-resource/lib/resource/models"; -import * as utils from 'util'; -import { AppServiceClient } from "../clients/azure/appServiceClient"; -import { ArmRestClient } from "../clients/azure/armRestClient"; -import { ApiVersions, AzureResourceClient } from "../clients/azure/azureResourceClient"; -import { openBrowseExperience } from '../configure'; -import * as templateHelper from '../helper/templateHelper'; -import { extensionVariables, MustacheContext, PipelineConfiguration, QuickPickItemWithData, TargetKind, TargetResourceType, WizardInputs } from "../model/models"; -import { LocalPipelineTemplate, PreDefinedDataSourceIds, TemplateParameter, TemplateParameterType } from '../model/templateModels'; -import * as constants from '../resources/constants'; -import { Messages } from "../resources/messages"; -import { TelemetryKeys } from "../resources/telemetryKeys"; -import { Utilities } from "../utilities/utilities"; -import { getSubscriptionSession } from "./azureSessionHelper"; -import { ControlProvider } from "./controlProvider"; -import { MustacheHelper } from "./mustacheHelper"; -import { telemetryHelper } from "./telemetryHelper"; - -export class TemplateParameterHelper { - public static getParameterForTargetResourceType(parameters: TemplateParameter[], targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): TemplateParameter { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - return parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - } - - public static getParameterValueForTargetResourceType(pipelineConfiguration: PipelineConfiguration, targetResourceType: TargetResourceType, targetResourceKind?: TargetKind): GenericResource { - let dataSourceIdForResourceType = TemplateParameterHelper.convertAzureResourceToDataSourceId(targetResourceType, targetResourceKind); - let resourceTemplateParameter = (pipelineConfiguration.template as LocalPipelineTemplate).parameters.find((parameter) => { return (parameter.type === TemplateParameterType.GenericAzureResource && parameter.dataSourceId.startsWith(dataSourceIdForResourceType)); }); - if (!resourceTemplateParameter) { - throw utils.format(Messages.azureResourceTemplateParameterCouldNotBeFound, targetResourceType); - } - - let parameterValue: GenericResource = pipelineConfiguration.params[resourceTemplateParameter.name]; - if (!parameterValue) { - throw utils.format(Messages.parameterWithNameNotSet, resourceTemplateParameter.name); - } - - return parameterValue; - } - - public static getMatchingAzureResourceTemplateParameter(resource: GenericResource, templateParameters: TemplateParameter[]): TemplateParameter { - if (!resource || !templateParameters) { - return null; - } - - let resourceTargetType = TemplateParameterHelper.convertAzureResourceToDataSourceId(resource.type, resource.kind); - let matchedParam = templateParameters.find((templateParameter) => { return templateParameter.dataSourceId.toLowerCase() === resourceTargetType.toLowerCase(); }); - - if (matchedParam) { - return matchedParam; - } - - return null; - } - - public async setParameters(parameters: TemplateParameter[], inputs: WizardInputs): Promise { - if (!!parameters && parameters.length > 0) { - for (let parameter of parameters) { - if (!inputs.pipelineConfiguration.params[parameter.name]) { - try { - await this.getParameterValue(parameter, inputs); - } - catch (err) { - if (!inputs.pipelineConfiguration.params[parameter.name] && !!parameter.defaultValue) { - inputs.pipelineConfiguration.params[parameter.name] = parameter.defaultValue; - } - else { - throw err; - } - } - } - } - } - } - - private static convertAzureResourceToDataSourceId(targetType: TargetResourceType, targetKind: TargetKind): string { - return targetKind ? targetType + ":" + targetKind : targetType; - } - - private async getParameterValue(parameter: TemplateParameter, inputs: WizardInputs): Promise { - if (!!parameter) { - switch (parameter.type) { - case TemplateParameterType.String: - case TemplateParameterType.Boolean: - await this.getStringParameter(parameter, inputs); - break; - case TemplateParameterType.GenericAzureResource: - await this.getAzureResourceParameter(parameter, inputs); - break; - case TemplateParameterType.SecureString: - default: - throw new Error(utils.format(Messages.parameterOfTypeNotSupported, parameter.type)); - } - } - } - - private async getAzureResourceParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - if (!inputs.subscriptionId) { - await this.setSubscription(inputs); - } - - let azureResourceClient = new AzureResourceClient(inputs.azureSession.credentials, inputs.subscriptionId); - if (!!parameter) { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.ACR: - case PreDefinedDataSourceIds.AKS: - let azureResourceListPromise = azureResourceClient.getResourceList(parameter.dataSourceId, true) - .then((list) => list.map(x => { return { label: x.name, data: x }; })); - while (1) { - let selectedResource = await controlProvider.showQuickPick( - parameter.name, - azureResourceListPromise, - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.dataSourceId)); - - let detailedResource = await this.tryGetSelectedResourceById( - selectedResource.data.id, - azureResourceClient, - ApiVersions.get(parameter.dataSourceId === PreDefinedDataSourceIds.ACR ? TargetResourceType.ACR : TargetResourceType.AKS)); - if (!detailedResource) { - throw utils.format(Messages.unableToGetSelectedResource, selectedResource.label); - } - - if (parameter.dataSourceId === PreDefinedDataSourceIds.ACR) { - // dynamic validation for ACR - if (detailedResource.properties.adminUserEnabled === false) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.onlyAdminEnabledRegistriesAreAllowed); - continue; - } - } - else { - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(selectedResource.data.id)); - - // handling case senstivity issue of httpApplicationRouting - if (detailedResource.properties.addonProfiles) { - let addonProfiles = JSON.parse(JSON.stringify(detailedResource.properties.addonProfiles).toLowerCase()); - if (addonProfiles.httpapplicationrouting) { - addonProfiles.httpApplicationRouting = addonProfiles.httpapplicationrouting; - delete addonProfiles['httpapplicationrouting']; - detailedResource.properties.addonProfiles = addonProfiles; - } - } - - // dynamic validation for AKS cluster - try { - let armRestClient = new ArmRestClient(inputs.azureSession); - await armRestClient.getAksKubeConfig(detailedResource.id); - } - catch (error) { - controlProvider.showErrorMessage(constants.ResourceDynamicValidationFailure, Messages.unableToGetAksKubeConfig); - continue; - } - } - - inputs.pipelineConfiguration.params[parameter.name] = detailedResource; - break; - } - break; - case PreDefinedDataSourceIds.WindowsApp: - case PreDefinedDataSourceIds.LinuxApp: - case PreDefinedDataSourceIds.FunctionApp: - case PreDefinedDataSourceIds.LinuxFunctionApp: - let selectedPipelineTemplate = inputs.pipelineConfiguration.template; - let matchingPipelineTemplates = templateHelper.getPipelineTemplatesForAllWebAppKind(inputs.sourceRepository.repositoryProvider, - selectedPipelineTemplate.label, selectedPipelineTemplate.language, selectedPipelineTemplate.targetKind); - - let appServiceClient = new AppServiceClient(inputs.azureSession.credentials, inputs.azureSession.environment, inputs.azureSession.tenantId, inputs.subscriptionId); - - let webAppKinds = matchingPipelineTemplates.map((template) => template.targetKind); - let selectedResource: QuickPickItemWithData = await controlProvider.showQuickPick( - Messages.selectTargetResource, - appServiceClient.GetAppServices(webAppKinds) - .then((webApps) => webApps.map(x => { return { label: x.name, data: x }; })), - { placeHolder: Messages.selectTargetResource }, - TelemetryKeys.AzureResourceListCount); - - telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash((selectedResource.data).id)); - if (await appServiceClient.isScmTypeSet((selectedResource.data).id)) { - await openBrowseExperience((selectedResource.data).id); - throw Error(Messages.setupAlreadyConfigured); - } - else { - inputs.pipelineConfiguration.params[constants.TargetResource] = selectedResource.data; - inputs.pipelineConfiguration.template = matchingPipelineTemplates.find((template) => template.targetKind === inputs.targetResource.resource.kind); - } - break; - default: - throw new Error(utils.format(Messages.parameterWithDataSourceOfTypeNotSupported, parameter.dataSourceId)); - } - } - } - - private async setSubscription(inputs: WizardInputs): Promise { - // show available subscriptions and get the chosen one - let subscriptionList = extensionVariables.azureAccountExtensionApi.filters.map((subscriptionObject) => { - return { - label: `${subscriptionObject.subscription.displayName}`, - data: subscriptionObject, - description: `${subscriptionObject.subscription.subscriptionId}` - }; - }); - - let selectedSubscription: QuickPickItemWithData = await new ControlProvider().showQuickPick( - constants.SelectSubscription, - subscriptionList, - { placeHolder: Messages.selectSubscription }, - TelemetryKeys.SubscriptionListCount); - inputs.subscriptionId = selectedSubscription.data.subscription.subscriptionId; - inputs.azureSession = await getSubscriptionSession(inputs.subscriptionId); - } - - private async tryGetSelectedResourceById(selectedResourceId: string, azureResourceClient: AzureResourceClient, getResourceApiVersion?: string): Promise { - try { - let detailedResource = null; - if (getResourceApiVersion) { - detailedResource = await azureResourceClient.getResource(selectedResourceId, getResourceApiVersion); - } - else { - detailedResource = await azureResourceClient.getResource(selectedResourceId); - } - - if (detailedResource) { - return detailedResource; - } - } - catch (err) { - console.log(err); - // continue; - } - - return null; - } - - private async getStringParameter(parameter: TemplateParameter, inputs: WizardInputs): Promise { - let controlProvider = new ControlProvider(); - - let mustacheContext = new MustacheContext(inputs); - if (!parameter.dataSourceId) { - if (parameter.defaultValue) { - let renderedDefaultValue = MustacheHelper.render(parameter.defaultValue, mustacheContext); - inputs.pipelineConfiguration.params[parameter.name] = renderedDefaultValue; - } - else { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showInputBox( - parameter.name, - { - placeHolder: parameter.displayName - } - ); - } - } - else { - switch (parameter.dataSourceId) { - case PreDefinedDataSourceIds.RepoAnalysis: - if (parameter.name.toLowerCase() === 'containerport') { - var port = templateHelper.getDockerPort(inputs.sourceRepository.localPath); - port = port ? port : parameter.defaultValue; - - inputs.pipelineConfiguration.params[parameter.name] = port; - } - break; - default: - if (parameter.options) { - inputs.pipelineConfiguration.params[parameter.name] = await controlProvider.showQuickPick( - parameter.name, - parameter.options ? parameter.options.map(x => { return { label: x.key, data: x.value }; }) : [], - { placeHolder: parameter.displayName }, - utils.format(TelemetryKeys.pickListCount, parameter.name)); - } - else if (!inputs.pipelineConfiguration.params[parameter.name]) { - inputs.pipelineConfiguration.params[parameter.name] = MustacheHelper.render(parameter.defaultValue, mustacheContext); - } - } - } - } -} \ No newline at end of file diff --git a/src/configure/model/Contracts.ts b/src/configure/model/Contracts.ts deleted file mode 100644 index 7db20fae..00000000 --- a/src/configure/model/Contracts.ts +++ /dev/null @@ -1,294 +0,0 @@ -export interface ExtendedInputDescriptor extends InputDescriptor { - /** - * Name of the data source which can be used to fetch possible values for this input - */ - dataSourceId: string; - /** - * Default value of the input. If PossibleValues is specified, default value must of one of those - */ - defaultValue: string; - /** - * List of dynamic remote url-based validations which can be performed on the input. - */ - dynamicValidations: InputDynamicValidation[]; - /** - * Name of the group to which this input belongs - */ - groupId: string; - /** - * Mode in which the value of this input should be entered. Currently supported values - TextBox and Combo - */ - inputMode: InputMode; - /** - * Specifies whether a value for this input must be provided - */ - isRequired: boolean; - /** - * Localized name which can be shown as a label for the input - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for input placement, decoration, summary, etc - */ - properties: { [key: string]: any; }; - /** - * Static validation which can be performed on the input - */ - staticValidation: InputStaticValidation; - /** - * Specifies the name which can be shown as sublabel for the input control - */ - sublabel: string; - /** - * Defines the visibility rule of the input. - */ - visibleRule: string; -} - - -/** - * Extended version of pipeline template. It will additionally contains UX hints and other information which can be helpful to draw UX for this template - */ -export interface ExtendedPipelineTemplate { - /** - * Description of the CI/CD pipeline which is enabled by this template - */ - description: string; - /** - * Unique id of the pipeline template - */ - id: string; - /** - * List of the inputs required to create CI/CD pipeline - */ - - attributes?: { [key: string]: string; }; - - parameters?: Parameters; - - configuration?: Configuration; -} - -export interface Configuration { - pipelineDefinition?: { [key: string]: string; }; - - assets?: Asset[]; - - variables?: Variable[]; - - imports?: any; -} - -export interface Parameters { - - /** - * List of the inputs required to create CI/CD pipeline - */ - inputs?: ExtendedInputDescriptor[]; - - /** - * List of data sources associated with this template - */ - dataSources?: DataSource[]; - /** - * List of input groups - */ - groups?: InputGroup[]; - -} - -export interface DataSource { - /** - * Stem of the remote URL to which request will be made. URL base is assumed to be Azure ARM URL base. - */ - endpointUrlStem: string; - /** - * HTTP method for request - */ - httpMethod?: string; - id: string; - /** - * Serialized string for request body - */ - requestBody?: string; - /** - * Jsonpath selector to get result from response - */ - resultSelector?: string; - /** - * Result template which will be used to transform the data source result. - */ - resultTemplate?: string; -} - -export interface InputGroup { - /** - * Unique id for a group - */ - id: string; - /** - * Localized name which can be shown as a label for the group - */ - name: string; - /** - * Additional properties for the input group. This can contains UI hints for group placement etc. - */ - properties: { [key: string]: string; }; -} - -/** - * Mode in which an input must be entered in UI - */ -export enum InputMode { - /** - * This input should not be shown in the UI - */ - None = 0, - /** - * An input text box should be shown - */ - TextBox = 10, - /** - * An password input box should be shown - */ - PasswordBox = 20, - /** - * A select/combo control should be shown - */ - Combo = 30, - /** - * Checkbox should be shown(for true/false values) - */ - CheckBox = 40, - /** - * A control for choosing azure subscription should be shown - */ - AzureSubscription = 50, - /** - * A control for choosing AAD tenant - */ - TenantId = 60, - /** - * A control to acquire AAD access token. Can be hidden if acquiring access token is non-interactive - */ - AadAccessToken = 70, - /** - * A control for choosing one of the options from radio buttons shown - */ - RadioButtons = 80, - /** - * A control for choosing virtual machine size - */ - VirtualMachineSizeControl = 90 -} - -export enum InputDataType { - String = 0, - SecureString = 1, - Int = 2, - Bool = 3, - Authorization = 4 -} - -export interface InputDescriptor { - /** - * Description of what this input is used for - */ - description: string; - /** - * Identifier for the input - */ - id: string; - /** - * Possible values that this input can take - */ - possibleValues: InputValue[]; - /** - * Data type of the input - */ - // tslint:disable-next-line:no-reserved-keywords - type: InputDataType; -} - -/** - * A dynamic validation for input value. Validation will done based on response from a data source - */ -export interface InputDynamicValidation { - /** - * Name of the data source to which a HTTP request will be made - */ - dataSourceId: string; - /** - * Error message to show if this dynamic validation fails - */ - errorMessage: string; - /** - * Result template which will transform data source response into success or failure - */ - resultTemplate: string; -} - -export interface InputStaticValidation { - /** - * Error message to show if static validation fails - */ - errorMessage: string; - /** - * Maximum supported length of a string type input - */ - maxLength: number; - /** - * Maximum supported value for a numeric type input - */ - maxValue: number; - /** - * Minimum supported length of a string type input - */ - minLength: number; - /** - * Minimum supported value for a numeric type input - */ - minValue: number; - /** - * Regex pattern against which value will be matched - */ - pattern: string; - /** - * Regex flags for pattern matching like 'i' for ignore case, etc - */ - regexFlags: string; -} - -/** - * Information about a single value for an input - */ -export interface InputValue { - /** - * The text to show for the display of this value - */ - displayValue: string; - /** - * The value to store for this input - */ - value: string; -} - -export interface Variable { - id: string; - value: string; - logTelemetry?: boolean; - hashTelemetryValue?: boolean; -} - -export interface Asset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - stage: ConfigurationStage; - inputs: { [key: string]: any }; -} - -export enum ConfigurationStage { - Pre = "Pre", - Post = "Post" -}; diff --git a/src/configure/model/azureDevOps.ts b/src/configure/model/azureDevOps.ts deleted file mode 100644 index 37bacc89..00000000 --- a/src/configure/model/azureDevOps.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RepositoryProvider } from "./models"; - -export interface BuildDefinition { - name: string; - path: string; - // tslint:disable-next-line:no-reserved-keywords - type: number; - quality: number; - process: YamlProcess; - project: { id: string, name: string }; - repository: BuildDefinitionRepository; - triggers: Array; - queue: { id: number }; - properties: { [key: string]: string }; -} - -export interface BuildDefinitionRepository { - id: string; - name: string; - // tslint:disable-next-line:no-reserved-keywords - type: RepositoryProvider; - defaultBranch: string; - url: string; - properties?: BuildDefinitionRepositoryProperties; -} - -export interface BuildDefinitionRepositoryProperties { - connectedServiceId: string; - apiUrl: string; - branchesUrl: string; - cloneUrl: string; - defaultBranch: string; - fullName: string; - refsUrl: string; -} - -export interface BuildDefinitionTrigger { - triggerType: number; - settingsSourceType: number; - batchChanges: boolean; -} - -export interface YamlProcess { - // tslint:disable-next-line:no-reserved-keywords - type: number; - yamlFileName: string; -} - -export interface Build { - id: string; - definition: { id: number, url?: string }; - project: { id: string }; - sourceBranch: string; - sourceVersion: string; - _links?: { web: { href: string } }; -} - -export interface Repository { - id: string; - name: string; - remoteUrl: string; -} \ No newline at end of file diff --git a/src/configure/model/models.ts b/src/configure/model/models.ts deleted file mode 100644 index dc5055e1..00000000 --- a/src/configure/model/models.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { SubscriptionModels } from 'azure-arm-resource'; -import { GenericResource } from 'azure-arm-resource/lib/resource/models'; -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ServiceClientCredentials } from 'ms-rest'; -import { AzureEnvironment } from 'ms-rest-azure'; -import { ExtensionContext, OutputChannel, QuickPickItem, workspace } from 'vscode'; -import { IAzureUserInput, ITelemetryReporter, UIExtensionVariables } from 'vscode-azureextensionui'; -import { Messages } from '../resources/messages'; -import { PipelineTemplate } from './templateModels'; - -class ExtensionVariables implements UIExtensionVariables { - public azureAccountExtensionApi: AzureAccountExtensionExports; - public context: ExtensionContext; - public outputChannel: OutputChannel; - public reporter: ITelemetryReporter; - public ui: IAzureUserInput; - public enableGitHubWorkflow: boolean; - public remoteConfigurerEnabled: boolean; - public isLocalRepo: boolean; - - constructor() { - this.enableGitHubWorkflow = !workspace.getConfiguration().get('deployToAzure.UseAzurePipelinesForGithub'); - this.remoteConfigurerEnabled = true; - this.isLocalRepo = false; - } -} - -let extensionVariables = new ExtensionVariables(); -export { extensionVariables }; - -export class WizardInputs { - organizationName: string; - project: DevOpsProject; - isNewOrganization: boolean; - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters = new AzureParameters(); - repositoryAnalysisApplicationSettings: ApplicationSettings; - pipelineConfiguration: PipelineConfiguration = new PipelineConfiguration(); - azureSession: AzureSession; - subscriptionId: string; - githubPATToken?: string; - potentialTemplates?: PipelineTemplate[]; -} - -export class AzureParameters { - resource: GenericResource; - serviceConnectionId: string; -} - -export class Organization { - accountId: string; - accountName: string; - accountUri: string; - properties: {}; - isMSAOrg: boolean; -} - -export class GitHubOrganization { - login: string; - id: number; - url: string; - repos_url: string; - isUserAccount?: boolean = false; -} - -export class GitHubRepo { - id: string; - name: string; - orgName: string; - html_url: string; - description: string; -} - -export class AzureSession { - environment: AzureEnvironment; - userId: string; - tenantId: string; - credentials: ServiceClientCredentials; -} - -export class PipelineConfiguration { - filePath: string; - template: PipelineTemplate; - workingDirectory: string; - params: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; -} - -export class MustacheContext { - constructor(inputs: WizardInputs) { - this.inputs = inputs.pipelineConfiguration.params; - this.assets = inputs.pipelineConfiguration.assets; - this.workingDirectory = inputs.pipelineConfiguration.workingDirectory; - this.sourceRepository = inputs.sourceRepository; - this.targetResource = inputs.targetResource; - this.repositoryAnalysisApplicationSettings = inputs.repositoryAnalysisApplicationSettings; - } - - inputs: { [key: string]: any } = {}; - assets: { [key: string]: any } = {}; - // we also need to remove working directory and make it an explicit parameter of template, which will be present as part of inputs. - workingDirectory: string; - // the below two properties will be removed during transition to parameterized templates. - sourceRepository: GitRepositoryParameters; - targetResource: AzureParameters; - repositoryAnalysisApplicationSettings: ApplicationSettings; -} - -export class QuickPickItemWithData implements QuickPickItem { - label: string; - data: any; - description?: string; - detail?: string; -} - -export enum ControlType { - None, - QuickPick, - InputBox -} - -export interface StringMap { - [key: string]: T; -} - -export class ParsedAzureResourceId { - public resourceId: string; - public subscriptionId: string; - public resourceGroup: string; - public resourceType: string; - public resourceProvider: string; - public resourceName: string; - public childResourceType?: string; - public childResource?: string; - - constructor(resourceId: string) { - if (!resourceId) { - throw new Error(Messages.resourceIdMissing); - } - - this.resourceId = resourceId; - this.parseId(); - } - - private parseId() { - // remove all empty parts in the resource to avoid failing in case there are leading/trailing/extra '/' - let parts = this.resourceId.split('/').filter((part) => !!part); - if (!!parts) { - for (let i = 0; i < parts.length; i++) { - switch (i) { - case 1: - this.subscriptionId = parts[i]; - break; - case 3: - this.resourceGroup = parts[i]; - break; - case 5: - this.resourceProvider = parts[i]; - break; - case 6: - this.resourceType = parts[i]; - break; - case 7: - this.resourceName = parts[i]; - break; - case 8: - this.childResourceType = parts[i]; - break; - case 9: - this.childResource = parts[i]; - break; - } - } - } - } -} - -export interface AzureAccountExtensionExports { - sessions: AzureSession[]; - subscriptions: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - filters: { session: AzureSession, subscription: SubscriptionModels.Subscription }[]; - waitForLogin: () => Promise; - waitForSubscriptions: () => Promise; -} - -export interface DevOpsProject { - id: string; - name: string; -} - -export interface GitRepositoryParameters { - repositoryProvider: RepositoryProvider; - repositoryName: string; - repositoryId: string; - remoteName: string; - remoteUrl: string; - branch: string; - commitId: string; - localPath: string; - serviceConnectionId?: string; // Id of the service connection in Azure DevOps -} - -export enum AzureConnectionType { - None, - AzureRMServicePrincipal, - AzureRMPublishProfile -} - -export interface Token { - session: AzureSession; - accessToken: string; - refreshToken: string; -} - -export interface AadApplication { - appId: string; - secret: string; - objectId: string; -} - -export interface GitBranchDetails { - remoteName: string; - branch: string; -} - -export interface WebAppSourceControl { - id: string; - name: string; - properties: { - repoUrl: string; - isGitHubAction: boolean; - branch: string; - }; -} - -export enum SourceOptions { - CurrentWorkspace = 'Current workspace', - BrowseLocalMachine = 'Browse local machine', - GithubRepository = 'Github repository' -} - -export enum RepositoryProvider { - Github = 'github', - AzureRepos = 'tfsgit' -} - -export enum TargetResourceType { - None = 'none', - WebApp = 'Microsoft.Web/sites', - AKS = 'Microsoft.ContainerService/ManagedClusters', - ACR = 'Microsoft.ContainerRegistry/registries' -} - -export enum ServiceConnectionType { - GitHub = 'github', - AzureRM = 'arm', - ACR = "containerRegistery", - AKS = 'azureKubernetes' -} - -export enum TargetKind { - WindowsApp = 'app', - FunctionApp = 'functionapp', - FunctionAppLinux = 'functionapp,linux', - FunctionAppLinuxContainer = 'functionapp,linux,container', - LinuxApp = 'app,linux', - LinuxContainerApp = 'app,linux,container' -} - -export enum SupportedLanguage { - NONE = 'none', - NODE = 'node', - PYTHON = 'python', - DOTNETCORE = 'dotnetcore', - DOTNET = 'dotnet', - DOCKER = 'docker' -} - -export interface IPredicate { - inputName: string; - condition: string; - inputValue: string; -} - -export interface IVisibilityRule { - predicateRules: IPredicate[]; - operator: string; -} - -export enum PipelineType { - AzurePipeline, - GitHubPipeline -} - -export interface IResourceNode { - resource: GenericResource; - subscriptionId: string; -} diff --git a/src/configure/model/provisioningConfiguration.ts b/src/configure/model/provisioningConfiguration.ts deleted file mode 100644 index d040f395..00000000 --- a/src/configure/model/provisioningConfiguration.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface Authorization { - scheme: string; - parameters: { [key: string]: string }; -} - -export interface CodeRepository { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; - defaultBranch: string; - authorizationInfo: Authorization; -} - -export interface ProvisioningConfiguration { - id: string; - pipelineTemplateId: string; - pipelineTemplateParameters: { [key: string]: string }; - branch: string; - provisioningMode: provisioningMode; - pipelineConfiguration?: DraftPipelineConfiguration; - result?: Result; -} - -export enum provisioningMode { - draft = "draft", - complete = "complete", -} - -export interface PipelineConfiguration { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: string; -} - -export interface CompletePipelineConfiguration extends PipelineConfiguration { - path: string; - commitId: string; -} - -export interface DraftPipelineConfiguration extends PipelineConfiguration { - files: File[]; -} - -export interface File { - content: string; - path: string; -} - -export interface Result { - status: string; - message: string; - pipelineConfiguration: PipelineConfiguration; -} diff --git a/src/configure/model/templateModels.ts b/src/configure/model/templateModels.ts deleted file mode 100644 index 2bc212ac..00000000 --- a/src/configure/model/templateModels.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ExtendedPipelineTemplate } from "./Contracts"; -import { AzureConnectionType, ServiceConnectionType, TargetKind, TargetResourceType } from "./models"; - -export enum TemplateType { - REMOTE, - LOCAL -} - -export interface PipelineTemplate { - label: string; - templateWeight: number; - templateType: TemplateType; - targetType: TargetResourceType; - targetKind: TargetKind; - language: string; -} - -export interface TemplateInfo { - templateId: string; - workingDirectory: string; - templateWeight: number; - templateDescription: string; - templateLabel: string; - attributes: TemplateAttributes; -} - -export interface RemotePipelineTemplate extends PipelineTemplate, ExtendedPipelineTemplate { - workingDirectory: string; - -} - -export interface LocalPipelineTemplate extends PipelineTemplate { - path: string; - enabled: boolean; - parameters?: TemplateParameter[]; - assets?: TemplateAsset[]; - // this should be removed as we will have endpoints/secrets as assets and not a first class property - azureConnectionType?: AzureConnectionType; -} - -export interface TemplateAttributes { - language: string; - buildTarget: string; - deployTarget: string; -} - -export interface TemplateParameter { - name: string; - displayName: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateParameterType; - dataSourceId?: string; - defaultValue?: any; - options?: { key: string, value: any }[]; -} - -export interface TemplateAsset { - id: string; - // tslint:disable-next-line:no-reserved-keywords - type: TemplateAssetType; -} - -export enum GitHubSecretType { - AKSKubeConfigSecret = 'aksKubeConfig', - AzureRM = 'arm', - ContainerRegistryUsername = "containerRegistryUsername", - ContainerRegistryPassword = "containerRegistryPassword" -} - -export enum TemplateParameterType { - GenericAzureResource, - Boolean, - SecureString, - String -} - -export enum TemplateAssetType { - AzureARMServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM, - AzureARMPublishProfileServiceConnection = "endpoint:" + ServiceConnectionType.AzureRM + ":publishProfile", - ACRServiceConnection = "endpoint:" + ServiceConnectionType.ACR, - AKSKubeConfigServiceConnection = "endpoint:" + ServiceConnectionType.AKS + ":kubeconfig", - - GitHubARM = "gitHubSecret:" + GitHubSecretType.AzureRM, - GitHubARMPublishProfile = "gitHubSecret:" + GitHubSecretType.AzureRM + ":publishProfile", - GitHubAKSKubeConfig = "gitHubSecret:" + GitHubSecretType.AKSKubeConfigSecret + ":kubeconfig", - GitHubRegistryUsername = "gitHubSecret:" + GitHubSecretType.ContainerRegistryUsername, - GitHubRegistryPassword = "gitHubSecret:" + GitHubSecretType.ContainerRegistryPassword, - File = "file" + ":" -} - -export let PreDefinedDataSourceIds = { - ACR: TargetResourceType.ACR, - AKS: TargetResourceType.AKS, - FunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionApp, - LinuxApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxApp, - LinuxContainerApp: TargetResourceType.WebApp + ":" + TargetKind.LinuxContainerApp, - LinuxFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinux, - LinuxContainerFunctionApp: TargetResourceType.WebApp + ":" + TargetKind.FunctionAppLinuxContainer, - WindowsApp: TargetResourceType.WebApp + ":" + TargetKind.WindowsApp, - - RepoAnalysis: 'RepoAnalysis' -}; diff --git a/src/configure/resources/constants.ts b/src/configure/resources/constants.ts deleted file mode 100644 index 532812bb..00000000 --- a/src/configure/resources/constants.ts +++ /dev/null @@ -1,203 +0,0 @@ -export const AzureDevOpsBaseUrl: string = "https://dev.azure.com"; -export const HostedVS2017QueueName: string = "Hosted VS2017"; -export const ReservedHostNames: string[] = [ - // Reserved names from https://dev.azure.com/mseng/AzureDevOps/_git/AzureDevOps?path=%2FMps%2FService%2FNameResolution%2FServicing%2FHost%2FDeployment%2FGroups%2FInstall%2FInstallNameResolutionService.xml&version=GBmaster - // Forbidden - "aisvc", - "cdn1", - "cdn2", - "cdn3", - "developers", - "elstest", - "events", - "hooks", - "integrate", - "launch", - "myname", - "servicefabric", - "sps", - "tfsodata", - "vssh", - "vsrm", - "yourname", - "app", - "deployment", - "services", - "teamfoundation", - "teamfoundationserver", - "tfs", - "ww", - "www", - "wwww", - - // MicrosoftReserved - "alm", - "almsearch", - "api", - "auditservice", - "azchatops", - "azdevchatops", - "azminicom", - "azboards", - "careers", - "cdn1", - "cdn2", - "code", - "codesmarts", - "dev", - "dl", - "docs", - "download", - "e", - "elstest", - "events", - "exchange", - "explore", - "feeds", - "forums", - "githubapp", - "githubapps", - "gdprdel", - "hooks", - "i2", - "i3", - "insightsportal", - "intellitrace", - "internetexplorer", - "jscript", - "launch", - "liveshare", - "lync", - "media", - "my", - "offer", - "orgsearch", - "pipelines", - "pipelinesapp", - "portal", - "premium", - "professional", - "project-cascade", - "promo", - "reg", - "skydrive", - "scaleunits", - "secretscan", - "servicedeployments", - "servicehosts", - "sps", - "sqlazure", - "ssh", , - "start", - "status", , - "statusalt1", - "status-alt1", - "support", - "taco", - "tfs", - "tfsapp", - "tfsodata", - "tutorials", - "ultimate", - "userext", - "video", - "vscatalog", - "vsdevprofile", - "vsdscops", - "vsengsaas", - "vsevidence", - "vskeros", - "vslicense", - "vsnotify", - "vsmps", - "vsrtc", - "vssh", - "vsodata", - "vspolicy", - "vssps", - "vsstage", - "vstmr", - "vstsusers", - "vsworking", - "web", - "webmatrix", - "webtooling", - "www", - "x-boards", - "x-pipes", - "x-ibizacd", - - // Based on past failures - "teamservices", - "java", - "beta" -]; - -export const PipelineTemplateLabels = { - SimpleApplicationToAppService: 'Simple application to App Service', - NodeJSWithNpmToAppService: 'Node.js with npm to App Service', - NodeJSWithGulpToAppService: 'Node.js with Gulp to App Service', - NodeJSWithGruntToAppService: 'Node.js with Grunt to App Service', - NodeJSWithAngularToAppService: 'Node.js with Angular to App Service', - NodeJSWithWebpackToAppService: 'Node.js with Webpack to App Service', - DotNetCoreWebAppToAppService: '.NET Core Web App to App Service', - NodeJSFunctionAppToAzureFunction: 'Node.js Function App to Azure Function', - DotNetCoreFunctionAppToAzureFunction: '.NET Core Function App to Azure Function', - PythonFunctionAppToLinuxAzureFunction: 'Python Function App to Linux Azure Function' -}; - -export const SelectFolderOrRepository = 'selectFolderOrRepository'; -export const SelectOrganization = 'selectOrganization'; -export const SelectProject = 'selectProject'; -export const EnterOrganizationName = 'enterOrganizationName'; -export const SelectPipelineTemplate = 'selectPipelineTemplate'; -export const SelectSubscription = 'selectSubscription'; -export const SelectWorkspace = 'selectWorkspace'; -export const SelectWebApp = 'selectWebApp'; -export const SelectFunctionApp = 'selectFunctionApp'; -export const GitHubPat = 'gitHubPat'; -export const SelectFromMultipleWorkSpace = 'selectFromMultipleWorkSpace'; -export const SelectRemoteForRepo = 'selectRemoteForRepo'; -export const VstsRmScmType = 'VSTSRM'; -export const BrowseNotAvailableConfigurePipeline = 'BrowseNotAvailableConfigurePipeline'; -export const DeploymentMessageType = 'CDDeploymentConfiguration'; -export const SetupAlreadyExists = 'SetupAlreadyExists'; -export const Browse = 'Browse'; -export const TargetResource = 'targetResource'; -export const ResourceDynamicValidationFailure = 'ResourceDynamicValidationFailure'; -export const EnterGithubRepositoryName = 'EnterGithubRepositoryName'; -export const SelectGitHubOrganization = 'selectGitHubOrganization'; - -//RepoAnalysis constants expected in response of Repository Analysis Service -export const RepoAnalysisConstants = { - //Common - Master: 'master', - - //Node - Gulp: 'gulp', - Grunt: 'grunt', - GulpFilePath: 'gulpFilePath', - GruntFilePath: 'gruntFilePath', - PackageFilePath: 'packageFilePath', - - //Python - Django: 'django', - RequirementsFilePath: 'requirementsFilePath', - - //Functions - AzureFunctions: 'azure:functions', - HostFilePath: 'hostFilePath' -}; - -export const deploymentManifest: string = "deployment"; -export const serviceManifest: string = "service"; -export const serviceIngressManifest: string = "service-ingress"; -export const ingressManifest: string = "ingress"; -export const azurePipeline: string = "Azure-pipeline"; -export const githubWorkflow: string = "Github-workflow"; -export const clientPropertyKey: string = "ms.client.vscode"; -export const inputModeProperty: string = "inputMode"; - -export const ExceptionType = { - UnauthorizedRequestException: 'UNAUTHORIZEDREQUESTEXCEPTION' -}; \ No newline at end of file diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts deleted file mode 100644 index e175deb8..00000000 --- a/src/configure/resources/messages.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class Messages { - public static acquireTokenFromRefreshTokenFailed: string = 'Acquiring token with refresh token failed. Error: %s.'; - public static addAzurePipelinesYmlFile: string = 'Added Azure Pipelines YAML definition.'; - public static addGitHubWorkflowYmlFile: string = 'Added GitHub Workflow YAML definition.'; - public static fetchingTemplates: string = 'Fetching templates'; - public static appKindIsNotSupported: string = 'App type "%s" is not yet supported.'; - public static azureResourceIsNull: string = 'ArgumentNullException: resource. The Azure target resource is empty, kindly select a resource and try again.'; - public static azureAccountExntesionUnavailable: string = 'Azure-Account extension could not be fetched. Please ensure it\'s installed and activated.'; - public static azureLoginRequired: string = 'Please sign in to your Azure account first.'; - public static branchRemoteMissing: string = `The current branch doesn't have a tracking branch, and the selected repository has no remotes. We're unable to create a remote tracking branch. Please [set a remote tracking branch](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---track) first, and then try this again.`; - public static browsePipeline: string = 'Browse Pipeline'; - public static cannotAddFileRemoteMissing: string = 'Couldn\'t add YAML file to your repo because the remote isn\'t set'; - public static cannotIdentifyRespositoryDetails: string = 'Couldn\'t get repository details. Ensure your repo is hosted on [Azure Repos](https://docs.microsoft.com/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static commitAndPush: string = 'Commit & push'; - public static commitFailedErrorMessage: string = `Commit failed due to error: %s`; - public static configuringPipelineAndDeployment: string = 'Configuring pipeline and proceeding to deployment...'; - public static couldNotAuthorizeEndpoint: string = 'Couldn\'t authorize endpoint for use in Azure Pipelines.'; - public static creatingAzureDevOpsOrganization: string = 'Creating Azure DevOps organization.'; - public static creatingAzureServiceConnection: string = 'Creating Azure deployment credentials with your subscription: %s'; - public static creatingKubernetesConnection: string = 'Creating connection with kubernetes resource: %s'; - public static creatingContainerRegistryConnection: string = 'Creating connection with container registry resource: %s'; - public static creatingGitHubServiceConnection: string = 'Creating GitHub service connection'; - public static discardPipeline: string = 'Discard pipeline'; - public static enterAzureDevOpsOrganizationName: string = 'Azure DevOps organization name where your pipeline will be hosted'; - public static enterGitHubPat: string = 'Enter GitHub personal access token (PAT), required to populate secrets that are used in the Github workflow'; - public static failedToCreateAzureDevOpsProject: string = 'Couldn\'t create a project in the Azure DevOps organization. Error: %s.'; - public static failedToCreateAzurePipeline: string = 'Couldn\'t configure pipeline. Error: %s'; - public static failedToDetermineAzureRepoDetails: string = 'Failed to determine Azure Repo details from remote url. Please ensure that the remote points to a valid Azure Repos url.'; - public static githubPatTokenErrorMessage: string = 'GitHub PAT token cannot be empty.'; - public static githubPatTokenHelpMessage: string = 'GitHub personal access token (PAT) with following permissions: Update github action workflows, read and write access to all repository data.'; - public static githubPatTokenHelpMessageGithubWorkflow: string = 'GitHub personal access token (PAT) with following permissions: read and write access to all repository data.'; - public static modifyAndCommitFile: string = 'Modify and save your YAML file. %s will commit this file, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static modifyAndCommitFileWithGitInitialization: string = 'Modify and save your YAML file to proceed with deployment.'; - public static noAgentQueueFound: string = 'No agent pool found named "%s".'; - public static notAGitRepository: string = 'Selected workspace is not a [Git](https://git-scm.com/docs/git) repository. Please select a Git repository.'; - public static notAzureRepoUrl: string = 'The repo isn\'t hosted with Azure Repos.'; - public static noWorkSpaceSelectedError: string = 'Please select a workspace folder to configure pipeline.'; - public static operationCancelled: string = 'Operation cancelled.'; - public static operationTimedOut: string = 'Operation timed out.'; - public static organizationNameReservedMessage: string = 'The organization name %s isn\'t available. Please try another organization name.'; - public static organizationNameStaticValidationMessage: string = 'Organization names must start and end with a letter or number and can contain only letters, numbers, and hyphens.'; - public static pipelineSetupSuccessfully: string = 'Pipeline set up successfully!'; - public static remoteRepositoryNotConfigured: string = 'Remote repository is not configured. This extension is compatible with [Azure Repos](https://docs.microsoft.com/en-us/azure/devops/repos/get-started) or [GitHub](https://guides.github.com/activities/hello-world/).'; - public static resourceIdMissing: string = 'Required argument "resourceId" is missing. Please pass the argument for getting resource.'; - public static resourceTypeIsNotSupported: string = '"%s" resources are not yet supported for configuring pipelines.'; - public static selectFolderLabel: string = 'Select source folder for configuring pipeline'; - public static selectOrganization: string = 'Select an Azure DevOps organization'; - public static selectPipelineTemplate: string = 'Select a pipeline template'; - public static selectProject: string = 'Select an Azure DevOps project'; - public static selectRemoteForBranch: string = 'Select the remote repository where you want to track your current branch'; - public static selectSubscription: string = 'Select the target Azure Subscription to deploy to your application'; - public static selectWorkspace: string = 'Select the working directory to your application'; - public static selectTargetResource: string = 'Select the target Azure Resource to deploy your application'; - public static selectWorkspaceFolder: string = 'Select a folder from your workspace to deploy'; - public static signInLabel: string = 'Sign In'; - public static signUpLabel: string = 'Sign Up'; - public static unableToCreateAzureServiceConnection: string = `Unable to store connection details for Azure subscription.\nOperation Status: %s\nMessage: %s\nService connection is not in ready state.`; - public static unableToCreateGitHubServiceConnection: string = `Unable to store connection details for GitHub.\nOperation Status: %s\nService connection is not in ready state.`; - public static retryFailedMessage: string = `Failed after retrying: %s times. Internal Error: %s`; - public static azureServicePrincipalFailedMessage: string = `Failed while creating Azure service principal.`; - public static roleAssignmentFailedMessage: string = `Failed while role assignement.`; - public static waitForAzureSignIn: string = `Waiting for Azure sign-in...`; - public static userCancelledExcecption = 'User cancelled the action'; - public static cannotFindPipelineUrlInMetaDataException = 'We were unable to find pipeline associated with the Azure Web App. Please click on "Browse Pipeline" to explore.'; - public static cannotFindOrganizationWithName = 'Unable to find organization with name: %s'; - public static browseNotAvailableConfigurePipeline = 'No pipeline is configured for this Azure Web App. Please click on "Deploy to Azure" to setup.'; - public static didNotRecieveAzureResourceNodeToProcess = 'Unable to browse the pipeline for you. Please raise an issue in the [repo](https://github.com/microsoft/vscode-deploy-azure/issues).'; - public static copyAndOpenLabel: string = 'Copy & Open'; - public static nextLabel: string = 'Next'; - public static githubWorkflowSetupSuccessfully: string = 'GitHub workflow set up successfully !'; - public static copyAndCreateSecretMessage: string = 'To deploy to Azure App Service via GitHub workflow, create a new secret with name \'%s\' in your repository. Copy the below secret value to add the secret'; - public static browseWorkflow: string = 'Browse Workflow'; - public static deploymentLogMessage: string = 'Configured from VS Code'; - public static setupAlreadyConfigured = 'Setup is already configured for your web app. Browse to know more about the existing setup.'; - public static settingUpGithubSecrets = 'Setting up GitHub Workflow secrets'; - public static parameterOfTypeNotSupported = 'Parameter of type %s is not supported.'; - public static parameterWithDataSourceOfTypeNotSupported = 'Parameter with data source Id: %s is not supported.'; - public static assetOfTypeNotSupportedForGitHub = 'Asset of type %s is not supported for GitHub workflows.'; - public static assetOfTypeNotSupportedForAzurePipelines = 'Asset of type %s is not supported for Azure Pipelines.'; - public static assetOfTypeNotSupported = 'Asset of type %s is not supported.'; - public static couldNotFindTargetResourceValueInParams = 'Could not find corresponding parameter value for template\'s target resource type: %s.'; - public static assetCreationOfTypeFailedWithError = 'Creation of asset of type: %s, failed with error: %s'; - public static azureResourceTemplateParameterCouldNotBeFound = 'Template has no parameter of type %s.'; - public static parameterWithNameNotSet = 'Parameter with name: %s has not yet been set, hence its value could not be found.'; - public static unableToFetchPasswordOfContainerRegistry = 'Password for container registry is could not be fetched. It is required for setting up AUTH with registry.'; - public static onlyAdminEnabledRegistriesAreAllowed = 'The chosen Container registry doesn\'t have admin user access enabled (allows access to registry with username password). Kindly choose a registry which has admin user access enabled.'; - public static unableToGetSelectedResource = 'Unable to fetch the selected azure resource: %s'; - public static unableToGetAksKubeConfig = 'We are unable to fetch kube config for the AKS cluster: %s, due to permission issues. Kindly choose a different one, over which you have access.'; - public static modifyAndCommitMultipleFiles: string = 'Modify and save your YAML files. %s will commit these files, push the branch \'%s\' to remote \'%s\' and proceed with deployment.'; - public static EmptyTagRowUnavailable = 'There is no space to create a new tag in the resource to store information to '; - public static valueRequired = 'The value cannot be empty'; - public static TemplateNotFound = 'Template not found'; - public static ResourceNotSupported = 'Resource not supported'; - public static minLengthMessage = "The minimum length allowed is %s"; - public static maxLengthMessage = "The maximum length allowed is %s"; - public static minValueMessage = "The value should be greater than or equals to %s"; - public static maxValueMessage = "The value should be less than or equals to %s"; - public static valueShouldBeNumber = "The value %s is not numberic"; - public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching %s value(s)"; - public static GettingNodeVersion = "Getting Node version to install"; - public static gettingTemplateFileAsset = "Getting template file asset to commit"; - public static gettingWorkflowFile = "Getting workflow file"; - public static templateFileNotFound = "Template file %s not found"; - public static selectGitHubOrganizationName = "Select a GitHub organization"; - public static createGitHubOrganization = "Create a GitHub Organization first to create GitHub repository."; - public static newGitHubRepositoryCreated = "New GitHub repository with the name '%s' has been created."; - public static cannotCreateGitHubRepository = "New GitHub repository could not be created as the repository with the same name already exists"; - public static languageNotSupported = "The language of the repository selected is not supported."; - public static UnableToGetTemplateParameters = "Unable to get parameters for the selected template."; - public static AnalyzingRepo = "Analyzing your repository"; - public static AzureLoginError = "Error in getting Azure login information. Please open 'Command Palette' and select 'Azure: Sign Out' and then invoke 'Deploy to Azure' extension."; - public static AdoDifferentTenantError = " One potential reason can be the AAD tenant of your Azure DevOps repository is different than the one you have been logged-in to VSCode. Open 'Command Palette' and select 'Azure: Sign Out' and then Sign-In to other tenant by invoking 'Deploy to Azure' extension"; - public static ConfiguringPipelineFailed = "Configuring provisioning pipeline failed due to %s"; - public static CreatingSPN = "Creating SPN"; - public static GeneratingWorkflowFiles = "Generating workflow file(s)"; - public static CreatingResourceGroup = "Creating resource group"; - public static ConfiguringGithubWorkflowAndDeployment = 'Configuring github workflow and proceeding to deployment...'; - public static ConfiguringGitubWorkflowFailed = 'Configuring github workflow failed due to %s'; - public static NoAzureSubscriptionFound = 'No Azure Subscription Found.'; - public static GithubRepoRequired = "The selected folder is not a GitHub repository.Please ensure your repository is hosted on GitHub and try again."; - public static GithubWorkflowSetupMultiFile: string = "The workflow files are pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GithubWorkflowSetup: string = "The workflow file is pushed to your Github repository([commit URL](%s)) and workflow is set up successfully !"; - public static GitHubPatInvalid: string = "The GitHub Personal Access token is Invalid. Please retry the command with a valid Personal Access token and ensure that it has permission for required scopes."; - public static UndefinedClientCredentials: string = "Undefined client credentials" -} diff --git a/src/configure/resources/telemetryKeys.ts b/src/configure/resources/telemetryKeys.ts deleted file mode 100644 index 76f14f6b..00000000 --- a/src/configure/resources/telemetryKeys.ts +++ /dev/null @@ -1,55 +0,0 @@ -export class TelemetryKeys { - public static CurrentUserInput: string = 'currentUserInput'; - public static RepoProvider: string = 'repoProvider'; - public static AzureLoginRequired: string = 'azureLoginRequired'; - public static JourneyId: string = 'journeyId'; - public static SourceRepoLocation: string = 'sourceRepoLocation'; - public static NewOrganization: string = 'newOrganization'; - public static ChosenTemplate: string = 'chosenTemplate'; - public static PipelineDiscarded: string = 'pipelineDiscarded'; - public static BrowsePipelineClicked: string = 'browsePipelineClicked'; - public static MultipleWorkspaceFolders: string = 'multipleWorkspaceFolders'; - public static GitFolderExists: string = 'gitFolderExists'; - public static ScmType: string = 'scmType'; - public static BrowsedDeploymentCenter = 'browsedDeploymentCenter'; - public static BrowsedExistingPipeline = 'browsedExistingPipeline'; - public static ClickedConfigurePipeline = 'clickedConfigurePipeline'; - public static UpdatedWebAppMetadata = 'updatedWebAppMetadata'; - public static NewDevOpsRepository = 'newDevOpsRepository'; - public static AzureLoginOption = 'azureLoginOption'; - public static PipelineAlreadyConfigured = 'pipelineAlreadyConfigured'; - public static SubscriptionId = 'subscriptionId'; - public static SelectedCICDProvider = 'selectedCICDProvider'; - public static RepoId = 'repoId'; - public static DisplayWorkflow = 'displayWorkflow'; - public static UnsupportedLanguage = 'unsupportedLanguage'; - public static RepositoryAnalysisFailed = 'repositoryAnalysisFailed'; - public static SelectedTemplate = 'selectedTemplate'; - public static SelectedTemplateType = 'selectedTemplateType'; - public static WorkflowFileName = 'workflowFileName'; - public static GitHubRepoCreated = 'GitHubRepoCreated'; - public static IsErrorWhitelisted = 'IsErrorWhitelisted'; - public static FF_UseGithubForCreatingNewRepository = 'FF_UseGithubForCreatingNewRepository'; - public static FF_UseAzurePipelinesForGithub = 'FF_UseAzurePipelinesForGithub'; - - public static resourceType = 'resourceType'; - public static resourceKind = 'resourceKind'; - public static resourceIdHash = 'resourceIdHash'; - - // Durations - public static ExtensionActivationDuration = 'extensionActivationDuration'; - public static CommandExecutionDuration = 'commandExecutionDuration'; - public static GitHubPatDuration = 'gitHubPatDuration'; - public static RepositoryAnalysisDuration = 'repositoryAnalysisDuration'; - public static TemplateServiceDuration = 'templateServiceDuration'; - - // Count of drop down items - public static OrganizationListCount = 'OrganizationListCount'; - public static ProjectListCount = 'ProjectListCount'; - public static AzureResourceListCount = 'AzureResourceListCount'; - public static WebAppListCount = 'WebAppListCount'; - public static PipelineTempateListCount = 'pipelineTempateListCount'; - public static SubscriptionListCount = 'SubscriptionListCount'; - public static WorkspaceListCount = 'WorkspaceListCount'; - public static pickListCount = 'pickList_%s_Count'; -} diff --git a/src/configure/resources/tracePoints.ts b/src/configure/resources/tracePoints.ts deleted file mode 100644 index ed6bcb6f..00000000 --- a/src/configure/resources/tracePoints.ts +++ /dev/null @@ -1,47 +0,0 @@ -export class TracePoints { - // Failure trace points - public static AddingContentToPipelineFileFailed = 'AddingContentToPipelineFileFailed'; - public static AzureLoginFailure = 'azureLoginFailure'; - public static AzureServiceConnectionCreateFailure = 'AzureServiceConnectionCreateFailure'; - public static CheckInPipelineFailure = 'checkInPipelineFailure'; - public static CreateAndQueuePipelineFailed = 'createAndBuildPipelineFailed'; - public static CreateNewOrganizationAndProjectFailure = 'CreateNewOrganizationAndProjectFailure'; - public static ExtractAzureResourceFromNodeFailed = 'extractAzureResourceFromNodeFailed'; - public static GetAzureDevOpsDetailsFailed = 'GetAzureDevOpsDetailsFailed'; - public static GetRepositoryDetailsFromRemoteUrlFailed = 'GetRepositoryDetailsFromRemoteUrlFailed'; - public static GetSourceRepositoryDetailsFailed = 'getSourceRepositoryDetailsFailed'; - public static GitHubServiceConnectionError = 'gitHubServiceConnectionError'; - public static PipelineFileCheckInFailed = 'PipelineFileCheckInFailed'; - public static PostDeploymentActionFailed = 'PostDeploymentActionFailed'; - public static CorruptMetadataForVstsRmScmType = 'CorruptMetadataForVstsRmScmType'; - public static GithubWorkflowSettingSecretsFailure = 'GithubWorkflowSettingSecretsFailure'; - public static AssetCreationFailure = 'AssetCreationFailure'; - public static ReadingDockerFileFailed = 'ReadingDockerFileFailed'; - public static CreatingManifestsFailed = 'CreatingManifestsFailed'; - public static ManifestsFolderCreationFailed = 'ManifestsFolderCreationFailed'; - public static RemoteServiceUrlFetchFailed = 'RemoteServiceUrlFetchFailed'; - public static EvaluateDynamicValidation = 'EvalauteDynamicValidation'; - public static InitializeDynamicValidation = 'InitializeDynamicValidation'; - public static SetInputControlValueFromRepoAnalysisResult = 'setInputControlValueFromRepoAnalysisResult'; - public static GetTemplateFile = 'GetTemplateFile'; - public static NoGitHubOrganizationExists = 'NoGitHubOrganizationExists'; - public static TemplateServiceCallFailed = 'TemplateServiceCallFailed'; - public static UnableToGetTemplateFile = 'UnableToGetTemplateFile'; - public static RepoAnalysisFailed = 'RepoAnalysisFailed'; - public static UnableToGetTemplateParameters = 'UnableToGetTemplateParameters'; - public static UnableToGetTemplateConfiguration = 'UnableToGetTemplateConfiguration'; - public static TemplateNotFound = 'TemplateNotFound'; - public static AzurePublishProfileCreationFailure = 'AzurePublishProfileCreationFailure'; - public static GitHubRepositoryCreationFailed = 'GitHubRepositoryCreationFailed'; - public static InitializeGitRepositoryFailed = 'InitializeGitRepositoryFailed'; - public static CommitAndPushPipelineFileFailed = 'CommitAndPushPipelineFileFailed'; - public static LanguageClientActivationFailed = 'LanguageClientActivationFailed'; - public static UnableToCreateProvisioningPipeline = 'UnableToCreateProvisioningPipeline'; - public static UnabletoGetProvisioningPipeline = 'UnabletoGetProvisioningPipeline'; - public static RemotePipelineConfiguringFailed = 'RemotePipelineConfiguringFailed'; - public static SPNCreationFailed = 'SPNCreationFailed'; - public static ConfiguringDraftPipelineFailed = "ConfiguringDraftPipelineFailed"; - public static ResourceGroupCreationFailed = "ResourceGroupCreationFailed"; - public static UndefinedArmAuthToken = "UndefinedArmAuthToken"; - public static GetPathToWorkFlowFileFailed = "GetPathToWorkFlowFileFailed"; -} diff --git a/src/configure/templateInputHelper/InputControl.ts b/src/configure/templateInputHelper/InputControl.ts deleted file mode 100644 index 1288c851..00000000 --- a/src/configure/templateInputHelper/InputControl.ts +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from 'util'; -import * as vscode from 'vscode'; -import { ControlProvider } from '../helper/controlProvider'; -import { MustacheHelper } from '../helper/mustacheHelper'; -import { telemetryHelper } from '../helper/telemetryHelper'; -import { DataSource, ExtendedInputDescriptor, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, QuickPickItemWithData, StringMap } from '../model/models'; -import { Messages } from '../resources/messages'; -import { TracePoints } from '../resources/tracePoints'; -import { DataSourceExpression } from './utilities/DataSourceExpression'; -import { DataSourceUtility } from './utilities/DataSourceUtility'; -import { StaticValidator } from './utilities/validation/StaticValidator'; - -const Layer: string = 'InputControl'; - -export class InputControl { - public dataSource: DataSourceExpression; - public dataSourceInputControls: Array; - public dataSourceInputs: Map; - public inputDescriptor: ExtendedInputDescriptor; - private value: any; - private controlType: ControlType; - private visible: boolean; - private validationDataSourceToInputsMap: Map; - private azureSession: AzureSession; - private _valuePendingValuation: any; - private controlProvider: ControlProvider; - - constructor(inputDescriptor: ExtendedInputDescriptor, value: any, controlType: ControlType, azureSession: AzureSession) { - this.inputDescriptor = inputDescriptor; - this.value = value; - this.visible = true; - this.controlType = controlType; - this.azureSession = azureSession; - this.dataSourceInputControls = []; - this.dataSourceInputs = new Map(); - this.controlProvider = new ControlProvider(); - } - - public getValue(): any { - return this.value; - } - - public setValue(defaultValue: string) { - this.value = defaultValue; - } - - public getInputDescriptor(): ExtendedInputDescriptor { - return this.inputDescriptor; - } - - public getInputControlId(): string { - return this.inputDescriptor.id; - } - - public getInputGroupId(): string { - return this.inputDescriptor.groupId; - } - - public getInputMode(): InputMode { - return this.inputDescriptor.inputMode; - } - - public getVisibleRule(): string { - return this.inputDescriptor.visibleRule; - } - - public isVisible(): boolean { - return this.visible; - } - - public setVisibility(value: boolean): void { - this.visible = value; - } - - public updateInputDescriptorProperty(key: string, value: any): void { - this.inputDescriptor[key] = value; - } - - public getInputDataType(): InputDataType { - return this.inputDescriptor.type; - } - - public updateControlType(controlType: ControlType): void { - this.controlType = controlType; - } - - public async setInputControlValue(): Promise { - if (!this.isVisible()) { - return; - } - if (!!this.dataSource) { - var dependentInputs = this._getDataSourceInputs(); - if (this.controlType === ControlType.None || this.controlType === ControlType.InputBox) { - this.value = await this.dataSource.evaluateDataSources(dependentInputs, this.azureSession); - let errorMessage = await this.triggerControlValueValidations(this.value); - if (errorMessage) { - vscode.window.showErrorMessage(errorMessage); - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - else if (this.controlType === ControlType.QuickPick) { - let listItems: Array = await vscode.window.withProgress( - { location: vscode.ProgressLocation.Notification, title: utils.format(Messages.fetchingInputMessage, this.inputDescriptor.name) }, - () => this.dataSource.evaluateDataSources(dependentInputs, this.azureSession)); - let selectedItem: QuickPickItemWithData; - while (1) { - selectedItem = await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { - placeHolder: this.inputDescriptor.name - }); - let errorMessage = await this.triggerControlValueValidations(selectedItem.data); - if (!errorMessage) { - break; - } - vscode.window.showErrorMessage(errorMessage); - } - this.value = selectedItem.data; - } - } - else { - if (this.controlType === ControlType.QuickPick) { - var listItems: Array<{ label: string, data: any }> = []; - if (!!this.inputDescriptor.possibleValues && this.inputDescriptor.possibleValues.length > 0) { - this.inputDescriptor.possibleValues.forEach((item) => { - listItems.push({ label: item.displayValue, data: item.value }); - }); - } - else if (this.inputDescriptor.inputMode === InputMode.RadioButtons) { - listItems.push({ label: "Yes", data: "true" }); - listItems.push({ label: "No", data: "false" }); - } - this.value = (await this.controlProvider.showQuickPick(this.getInputControlId(), listItems, { placeHolder: this.inputDescriptor.name })).data; - } - else if (this.controlType === ControlType.InputBox) { - this.value = await this.controlProvider.showInputBox(this.getInputControlId(), { - value: this.value, - placeHolder: this.inputDescriptor.name, - validateInput: (value) => this.triggerControlValueValidations(value) - }); - } - } - } - - public getPropertyValue(propertyName: string, inputs?: StringMap): string { - return InputControl.getInputDescriptorProperty(this.inputDescriptor, propertyName, inputs); - } - - public static getInputDescriptorProperty(input: ExtendedInputDescriptor, propertyName: string, inputs?: StringMap): any { - var properties = input.properties; - var value: string; - - if (!!properties) { - value = properties[propertyName]; - if (!!value && !!inputs && typeof value === "string") { - return MustacheHelper.render(value, { inputs: inputs }) - } else if (!!value && !!inputs) { - return MustacheHelper.renderObject(value, { inputs: inputs }); - } - } - return value; - - } - - public setValidationDataSources(dataSourceToInputsMap: Map) { - this.validationDataSourceToInputsMap = dataSourceToInputsMap; - } - - public async triggerControlValueValidations(value: string): Promise { - this._valuePendingValuation = value; - let errorMessage = this.getStaticValidationsResult(value); - if (errorMessage) { - return Promise.resolve(errorMessage); - } - - let validationPromises: Promise[] = []; - this.inputDescriptor.dynamicValidations.forEach((validation: InputDynamicValidation) => { - validationPromises.push(this.evaluateDynamicValidation(validation, value)); - }); - - return await Promise.all(validationPromises) - .then((results: string[]) => { - results.forEach((result) => { - if (result) { - errorMessage = errorMessage.concat(result); - } - }); - return errorMessage; - }) - .catch((error) => { - return ""; - }); - } - - private _getDataSourceInputs(): { [key: string]: any } { - var inputs: { [key: string]: any } = {}; - for (var dataSourceInput of this.dataSourceInputControls) { - inputs[dataSourceInput.getInputControlId()] = dataSourceInput.getValue(); - } - return inputs; - } - - private getStaticValidationsResult(value: string): string { - let validationResult = ""; - if (this.inputDescriptor.isRequired) { - let result = StaticValidator.validateRequired(value); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (this.inputDescriptor.staticValidation) { - if (!!this.inputDescriptor.staticValidation.minLength || !!this.inputDescriptor.staticValidation.maxLength) { - let result = StaticValidator.validateLength(value, this.inputDescriptor.staticValidation.minLength, this.inputDescriptor.staticValidation.maxLength); - if (result) { - validationResult = validationResult.concat(result); - } - } - if (!!this.inputDescriptor.staticValidation.pattern) { - var regexPattern = this.inputDescriptor.staticValidation.pattern; - - let result = StaticValidator.validateRegex(value, regexPattern, this.inputDescriptor.staticValidation.regexFlags || ""); - if (result) { - validationResult = this.inputDescriptor.staticValidation.errorMessage ? validationResult : validationResult.concat(result); - } - } - if (this.inputDescriptor.type === InputDataType.Int && (!!this.inputDescriptor.staticValidation.minValue || !!this.inputDescriptor.staticValidation.maxValue)) { - let result = StaticValidator.validateNumberValue(value, this.inputDescriptor.staticValidation.minValue, this.inputDescriptor.staticValidation.maxValue); - if (result) { - validationResult = validationResult.concat(result); - } - } - } - return validationResult; - } - - private async evaluateDynamicValidation(validation: InputDynamicValidation, value: string): Promise { - var requiredDataSource: DataSource = null; - this.validationDataSourceToInputsMap.forEach((inputControlArray: InputControl[], dataSource: DataSource) => { - if (dataSource.id === validation.dataSourceId) { - requiredDataSource = dataSource; - } - }); - - var requiredInputsValueMap: StringMap = {}; - var allRequiredInputValuesAvailable: boolean = true; - this.validationDataSourceToInputsMap.get(requiredDataSource).forEach((descriptor) => { - if (!descriptor.getValue()) { - allRequiredInputValuesAvailable = false; - return; - } - - requiredInputsValueMap[descriptor.getInputControlId()] = descriptor.getValue(); - }); - // setting the value for the current input with the current value passed as the value might have changed since this validation call was invoked, - requiredInputsValueMap[this.inputDescriptor.id] = value; - - if (allRequiredInputValuesAvailable) { - return DataSourceUtility.evaluateDataSource(requiredDataSource, requiredInputsValueMap, this.azureSession) - .then((result) => { - if (value === this._valuePendingValuation) { - if (!result) { - return validation.errorMessage; - } - - var resultObject = JSON.parse(result); - - if (resultObject && resultObject.value === "true") { - return null; - } - else { - return result && resultObject.message || validation.errorMessage; - } - } - else { - // The value of control has been changed, therefore resolve it as the validation of current value will override - return null; - } - }) - .catch((error) => { - if (!(requiredDataSource.resultTemplate && requiredDataSource.resultTemplate.toLowerCase() === "false")) { - telemetryHelper.logError(Layer, TracePoints.EvaluateDynamicValidation, error); - } - return null; - }); - } - else { - // Resolve as valid here as other validation for required input will be shown - return null; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/InputControlProvider.ts b/src/configure/templateInputHelper/InputControlProvider.ts deleted file mode 100644 index fb876d02..00000000 --- a/src/configure/templateInputHelper/InputControlProvider.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { MustacheHelper } from "../helper/mustacheHelper"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { DataSource, ExtendedInputDescriptor, ExtendedPipelineTemplate, InputDataType, InputDynamicValidation, InputMode } from "../model/Contracts"; -import { AzureSession, ControlType, IPredicate, StringMap } from '../model/models'; -import * as constants from '../resources/constants'; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; -import { RepoAnalysisSettingInputProvider } from "./RepoAnalysisSettingInputProvider"; -import { DataSourceExpression } from "./utilities/DataSourceExpression"; -import { DataSourceUtility } from "./utilities/DataSourceUtility"; -import { InputControlUtility } from "./utilities/InputControlUtility"; -import { VisibilityHelper } from "./utilities/VisibilityHelper"; - -const Layer: string = "InputControlProvider"; - -export class InputControlProvider { - private _pipelineTemplate: ExtendedPipelineTemplate; - private _inputControlsMap: Map; - private azureSession: AzureSession; - private repoAnalysisSettingInputProvider: RepoAnalysisSettingInputProvider; - private _context: StringMap; - - constructor(azureSession: AzureSession, pipelineTemplate: ExtendedPipelineTemplate, context: StringMap) { - this._pipelineTemplate = pipelineTemplate; - this._inputControlsMap = new Map(); - this.azureSession = azureSession; - this.repoAnalysisSettingInputProvider = new RepoAnalysisSettingInputProvider(context['repoAnalysisSettings'] as ApplicationSettings[]); - this._context = context; - this._createControls(); - } - - public async getAllPipelineTemplateInputs(): Promise<{ [key: string]: any }> { - let parameters: { [key: string]: any } = {}; - for (let inputControl of this._inputControlsMap.values()) { - if (!!inputControl.getPropertyValue(constants.clientPropertyKey)) { - this.overrideParameters(inputControl); - } - this._setInputControlDataSourceInputs(inputControl); - this._initializeDynamicValidations(inputControl); - if (this.repoAnalysisSettingInputProvider.inputFromRepoAnalysisSetting(inputControl)) { - await this.repoAnalysisSettingInputProvider.setInputControlValueFromRepoAnalysisResult(inputControl); - } - else { - this._setInputControlVisibility(inputControl); - this._setupInputControlDefaultValue(inputControl); - await inputControl.setInputControlValue(); - } - parameters[inputControl.getInputControlId()] = inputControl.getValue(); - } - return parameters; - } - - private overrideParameters(inputControl: InputControl): void { - let properties = inputControl.getPropertyValue(constants.clientPropertyKey); - let arrayofProperties = Object.keys(properties); - - arrayofProperties.forEach(element => { - let key = element.split(".", 2)[1]; - let newValue: any; - if (properties[element] !== null) { - let dependentInputControlArray = this._getInputDependencyArray(inputControl, [properties[element]], false); - let dependentClientInputMap = this._getClientDependencyMap(inputControl, [properties[element]]); - newValue = this._computeMustacheValue(properties[element], dependentInputControlArray, dependentClientInputMap); - } - inputControl.updateInputDescriptorProperty(key, newValue); - if (key === constants.inputModeProperty) { - let newInputMode: InputMode = (typeof newValue === "string") ? InputMode[newValue] : newValue; - let updatedControlType = InputControlUtility.getInputControlType(newInputMode); - inputControl.updateControlType(updatedControlType); - } - }); - } - - private _createControls(): void { - for (let input of this._pipelineTemplate.parameters.inputs) { - let inputControl: InputControl = null; - let inputControlValue = this._getInputControlValue(input); - if (input.type !== InputDataType.Authorization) { - let controlType: ControlType = InputControlUtility.getInputControlType(input.inputMode); - inputControl = new InputControl(input, inputControlValue, controlType, this.azureSession); - if (inputControl) { - this._inputControlsMap.set(input.id, inputControl); - } - } - } - } - - private _setInputControlDataSourceInputs(inputControl: InputControl): void { - let inputDes = inputControl.getInputDescriptor(); - if (!!inputDes.dataSourceId) { - var inputControl = this._inputControlsMap.get(inputDes.id); - inputControl.dataSource = DataSourceExpression.parse(inputDes.dataSourceId, this._pipelineTemplate.parameters.dataSources); - - if (inputControl.dataSource) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, inputControl.dataSource.getInputDependencyArray()); - if (dependentInputControlArray) { - inputControl.dataSourceInputControls.push(...dependentInputControlArray); - } - } else { - throw new Error(`Data source ${inputDes.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - } - - private _initializeDynamicValidations(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - - if (!!inputControl && !!inputDes.dynamicValidations && inputDes.dynamicValidations.length > 0) { - var dataSourceToInputsMap = new Map(); - inputDes.dynamicValidations.forEach((validation: InputDynamicValidation) => { - var validationDataSource = DataSourceUtility.getDataSourceById(this._pipelineTemplate.parameters.dataSources, validation.dataSourceId); - if (validationDataSource) { - dataSourceToInputsMap.set(validationDataSource, []); - - let dynamicValidationRequiredInputIds = DataSourceUtility.getDependentInputIdList(validationDataSource.endpointUrlStem); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.requestBody)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultTemplate)); - dynamicValidationRequiredInputIds = dynamicValidationRequiredInputIds.concat(DataSourceUtility.getDependentInputIdList(validationDataSource.resultSelector)); - - dynamicValidationRequiredInputIds = Array.from(new Set(dynamicValidationRequiredInputIds)); - dynamicValidationRequiredInputIds.forEach((dynamicValidationRequiredInputId) => { - var dependentInput = this._inputControlsMap.get(dynamicValidationRequiredInputId); - if (dependentInput) { - dataSourceToInputsMap.get(validationDataSource).push(dependentInput); - } else { - let error: Error = new Error(`Dependent input ${dynamicValidationRequiredInputId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - } else { - let error = new Error(`validation data source ${validation.dataSourceId} specified for input ${inputDes.id} is not present in pipeline template ${this._pipelineTemplate.id}`); - telemetryHelper.logError(Layer, TracePoints.InitializeDynamicValidation, error); - } - }); - inputControl.setValidationDataSources(dataSourceToInputsMap); - } - } - - private _setupInputControlDefaultValue(inputControl: InputControl): void { - var inputDes = inputControl.getInputDescriptor(); - var defaultValue = inputDes.defaultValue; - if (!defaultValue) { - return; - } - if (InputControlUtility.doesExpressionContainsDependency(defaultValue)) { - var dependentInputControlArray = this._getInputDependencyArray(inputControl, [defaultValue], false); - var dependentClientInputMap = this._getClientDependencyMap(inputControl, [defaultValue]); - defaultValue = this._computeMustacheValue(defaultValue, dependentInputControlArray, dependentClientInputMap); - } - if (defaultValue !== inputControl.getValue()) { - inputControl.setValue(defaultValue); - } - } - - private _computeMustacheValue(mustacheExpression: string, dependentInputControlArray: InputControl[], dependentClientInputMap: StringMap): any { - var dependentInputValues = this._getInputParameterValueIfAllSet(dependentInputControlArray); - if (dependentInputControlArray && dependentInputControlArray.length > 0 && !dependentInputValues) { - return ""; - } else { - return MustacheHelper.renderObject(mustacheExpression, { inputs: dependentInputValues, client: dependentClientInputMap }); - } - } - - private _getInputControlValue(inputDes: ExtendedInputDescriptor): string { - if (!!this._context && !!this._context - [inputDes.id]) { - return this._context[inputDes.id]; - } else { - return !inputDes.defaultValue - || InputControlUtility.doesExpressionContainsDependency(inputDes.defaultValue) - ? "" : inputDes.defaultValue; - } - } - - private _getClientDependencyMap(inputControl: InputControl, dependencyExpressionArray: string[]): StringMap { - var dependentClientControlMap: StringMap = {}; - var dependentClientInputs: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentClientInputs = dependentClientInputs.concat(InputControlUtility.getDependentClientIdList(dependencyExpression)); - } - } - - if (dependentClientInputs.length === 0) { - return null; - } - - var uniqueDependentClientInputs = dependentClientInputs.filter(function (item, pos) { - return dependentClientInputs.indexOf(item) === pos; - }); - - for (var clientInput of uniqueDependentClientInputs) { - var dependentInputControl = this._context[clientInput]; - if (dependentInputControl !== undefined) { - dependentClientControlMap[clientInput] = dependentInputControl; - } else { - throw new Error(`Dependent client input ${clientInput} specified is not present in client context.`); - } - } - return dependentClientControlMap; - } - - private _getInputDependencyArray(inputControl: InputControl, dependencyExpressionArray: string[], allowSelfDependency: boolean = true): InputControl[] { - var dependentInputControlArray: InputControl[] = []; - var dependentInputIds: string[] = []; - for (var dependencyExpression of dependencyExpressionArray) { - if (dependencyExpression) { - dependentInputIds = dependentInputIds.concat(InputControlUtility.getDependentInputIdList(dependencyExpression)); - } - } - - if (dependentInputIds.length === 0) { - return null; - } - - if (!allowSelfDependency && dependentInputIds.indexOf(inputControl.getInputControlId()) >= 0) { - throw new Error(`Input ${inputControl.getInputControlId()} has dependency on its own in pipeline template ${this._pipelineTemplate.id}.`); - } - - var uniqueDependentInputIds = dependentInputIds.filter(function (item, pos) { - return dependentInputIds.indexOf(item) === pos; - }); - - for (var inputId of uniqueDependentInputIds) { - var dependentInputControl = this._inputControlsMap.get(inputId); - if (dependentInputControl) { - dependentInputControlArray.push(dependentInputControl); - } else { - throw new Error(`Dependent input ${inputId} specified for input ${inputControl.getInputControlId()} is not present in pipeline template ${this._pipelineTemplate.id}`); - } - } - return dependentInputControlArray; - } - - private _getInputParameterValueIfAllSet(dependentInputControlArray: InputControl[], useDisplayValue: boolean = false): StringMap { - var dependentInputValuesMap: StringMap = {}; - if (!dependentInputControlArray) { - return null; - } - - for (var dependentInputControl of dependentInputControlArray) { - if (!dependentInputControl.getValue()) { - //Value of the parameter is not available, so rest of the input values will be useless. - throw new Error("Unable to get the input value, inputs order may not be correct"); - } - dependentInputValuesMap[dependentInputControl.getInputControlId()] = dependentInputControl.getValue(); - } - return dependentInputValuesMap; - } - - private _setInputControlVisibility(inputControl: InputControl): void { - var visibilityRule = VisibilityHelper.parseVisibleRule(inputControl.getVisibleRule()); - if (visibilityRule !== null && visibilityRule.predicateRules !== null && visibilityRule.predicateRules.length >= 0) { - var requiredInputControls: InputControl[] = []; - - visibilityRule.predicateRules.forEach((predicateRule: IPredicate) => { - try { - requiredInputControls = requiredInputControls.concat([this._inputControlsMap.get(predicateRule.inputName)]); - } - catch (exception) { - throw new Error("Input defined in visiblity rule doesn't exist"); - } - }); - inputControl.setVisibility(VisibilityHelper.evaluateVisibility(visibilityRule, requiredInputControls)); - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts b/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts deleted file mode 100644 index ceafd520..00000000 --- a/src/configure/templateInputHelper/RepoAnalysisSettingInputProvider.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ApplicationSettings } from "azureintegration-repoanalysis-client-internal"; -import { ControlProvider } from "../helper/controlProvider"; -import { telemetryHelper } from "../helper/telemetryHelper"; -import { InputDataType } from "../model/Contracts"; -import { TracePoints } from "../resources/tracePoints"; -import { InputControl } from "./InputControl"; - -const Layer: string = "RepoAnalysisSettingInputProvider"; - -export class RepoAnalysisSettingInputProvider { - private readonly repoAnalysisSettingKey: string = "repoAnalysisSettingKey"; - private repoAnalysisSettings: ApplicationSettings[]; - private selectedRepoAnalysisSettingIndex: number; - - constructor(repoAnalysisSettings: ApplicationSettings[]) { - this.repoAnalysisSettings = repoAnalysisSettings || []; - this.selectedRepoAnalysisSettingIndex = repoAnalysisSettings.length > 1 ? -1 : 0; - } - - public inputFromRepoAnalysisSetting(inputControl: InputControl): boolean { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - return !!repoAnalysisSettingKey && this.repoAnalysisSettings.length > 0; - } - - public async setInputControlValueFromRepoAnalysisResult(inputControl: InputControl): Promise { - const repoAnalysisSettingKey = inputControl.getPropertyValue(this.repoAnalysisSettingKey); - if (this.selectedRepoAnalysisSettingIndex !== -1) { - let value = this.repoAnalysisSettings[this.selectedRepoAnalysisSettingIndex].settings[repoAnalysisSettingKey]; - if (!value || (Array.isArray(value) && value.length === 0)) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - if (Array.isArray(value)) { - let selectedValue = value[0]; - if (value.length > 1) { - const possibleValues = value.map((element) => ({ label: element, data: element })); - - selectedValue = (await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { - placeHolder: inputControl.getInputDescriptor().name, - })).data; - } - value = selectedValue; - } - inputControl.setValue(value); - } - } else { - const settingIndexMap: Map = new Map(); - this.repoAnalysisSettings.forEach((analysisSetting, index: number) => { - if (!analysisSetting.settings[repoAnalysisSettingKey]) { - return; - } - let keyValue = analysisSetting.settings[repoAnalysisSettingKey]; - if (Array.isArray(keyValue)) { - if (keyValue.length === 0) { - return; - } - keyValue = keyValue.toString(); - } - - if (settingIndexMap.has(keyValue)) { - settingIndexMap.get(keyValue).push(index); - } else { - settingIndexMap.set(keyValue, [index]); - } - }); - if (settingIndexMap.size === 0) { - await this.setValueIfNotPresentInRepoAnalysis(inputControl, repoAnalysisSettingKey); - } else { - let possibleValues = Array.from(settingIndexMap.keys()).map((value) => ({ label: value, data: value })); - let selectedValue: { label: string, data: any }; - - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } - else { - // HACK: Temporarily default to first value without asking user. Remove this HACK later and uncomment the next line - selectedValue = possibleValues[0]; - // selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - if (settingIndexMap.get(selectedValue.data).length === 1) { - this.selectedRepoAnalysisSettingIndex = settingIndexMap.get(selectedValue.data)[0]; - } - - const repoAnalysisValue = this.repoAnalysisSettings[settingIndexMap.get(selectedValue.data)[0]].settings[repoAnalysisSettingKey]; - if (inputControl.getInputDataType() === InputDataType.String && Array.isArray(repoAnalysisValue)) { - possibleValues = repoAnalysisValue.map((value) => ({ label: value, data: value })); - if (possibleValues.length === 1) { - selectedValue = possibleValues[0]; - } else { - selectedValue = await new ControlProvider().showQuickPick(repoAnalysisSettingKey, possibleValues, { placeHolder: inputControl.getInputDescriptor().name }); - } - } - inputControl.setValue(selectedValue.data); - } - } - } - - private async setValueIfNotPresentInRepoAnalysis(inputControl: InputControl, repoAnalysisSettingKey: string): Promise { - const error = new Error(`RepostioryAnalysisSetting doesn't contain ${repoAnalysisSettingKey} for input ${inputControl.getInputControlId()}`); - telemetryHelper.logError(Layer, TracePoints.SetInputControlValueFromRepoAnalysisResult, error); - let value = inputControl.getInputDescriptor().defaultValue; - if (!value) { - value = await new ControlProvider().showInputBox(repoAnalysisSettingKey, { - placeHolder: inputControl.getInputDescriptor().name, - validateInput: (v) => inputControl.triggerControlValueValidations(v) - }); - } - return inputControl.setValue(value); - } -} diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts deleted file mode 100644 index cba7a370..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { DataSource } from "../../model/Contracts"; -import { AzureSession } from "../../model/models"; -import { DataSourceUtility } from "./DataSourceUtility"; - -export class DataSourceExpression { - public operator: Operator; - public leftChild?: DataSourceExpression; - public rightChild?: DataSourceExpression; - public value?: string; - - private _dataSources: DataSource[] = []; - - // Parses a dataSourceId string into an expression based on operators present in the id. - // NOTE: Currently only a simple expression of type "expr1 OPERATOR expr2" is supported. - public static parse(dataSourceId: string, dataSources: DataSource[]): DataSourceExpression { - this._validateDataSourceId(dataSourceId); - var id: string = dataSourceId.trim(); - var parts: any[] = DataSourceExpression._splitByOperator(id); - if (parts.length > 1) { - var leftChild: DataSourceExpression = DataSourceExpression.parse(parts[0].trim(), dataSources); - var rightChild: DataSourceExpression = DataSourceExpression.parse(parts[1].trim(), dataSources); - if (!leftChild && !rightChild) { - return null; - } - - return new DataSourceExpression( - parts[2], - leftChild, - rightChild, - null, - dataSources); - } - - if (!DataSourceUtility.getDataSourceById(dataSources, parts[0])) { - return null; - } - - return new DataSourceExpression( - Operator.UNDEFINED, - null, - null, - parts[0], - dataSources); - } - - public getInputDependencyArray(): string[] { - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return [dataSource.endpointUrlStem, dataSource.requestBody, dataSource.resultSelector, dataSource.resultTemplate]; - } - - var leftDependencyArray: string[] = []; - var rightDependencyArray: string[] = []; - if (this.leftChild) { - leftDependencyArray = this.leftChild.getInputDependencyArray(); - } - - if (this.rightChild) { - rightDependencyArray = this.rightChild.getInputDependencyArray(); - } - - return leftDependencyArray.concat(rightDependencyArray); - } - - public async evaluateDataSources(inputs: { [key: string]: any }, azureSession: AzureSession): Promise { - var dataPromises: Promise[] = []; - - if (this.operator === Operator.UNDEFINED) { - var dataSource = DataSourceUtility.getDataSourceById(this._dataSources, this.value); - return DataSourceUtility.evaluateDataSource(dataSource, inputs, azureSession); - } - - if (this.leftChild) { - dataPromises.push(this.leftChild.evaluateDataSources(inputs, azureSession)); - } - - if (this.rightChild) { - dataPromises.push(this.rightChild.evaluateDataSources(inputs, azureSession)); - } - - return Promise.all(dataPromises).then((result: any[]) => { - // If one of the data source evaluates to an array while other evaluates to a string, then take the array - if (Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; - } - - if (Array.isArray(result[1]) && !Array.isArray(result[0])) { - return result[1]; - } - - // If both data sources evaluate to string, then take that is not empty - if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0] || result[1]; - } - - if (Array.isArray(result[0]) && Array.isArray(result[1])) { - return DataSourceExpression._applyOperator(this.operator, result[0], result[1]); - } - }); - } - - private constructor(operator: Operator, leftChild: DataSourceExpression, rightChild: DataSourceExpression, value: string, dataSources: DataSource[]) { - this.operator = operator; - this.leftChild = leftChild; - this.rightChild = rightChild; - this.value = value; - this._dataSources = dataSources; - } - - private static _applyOperator( - operator: Operator, array1: Array<{ text: string, value: any, group?: string }>, - array2: Array<{ text: string, value: any, group?: string }>): Array<{ text: string, value: any, group?: string }> { - - switch (operator) { - case Operator.INTERSECT: - return array1.filter(item1 => { - return array2.some((item2) => { - return item2.value.toLowerCase() === item1.value.toLowerCase() - && ((!item2.group && !item1.group) || item2.group.toLowerCase() === item1.group.toLowerCase()); - }); - }); - default: - var error: string = `Data sources do not support operator ${operator}. Supported operators are: INTERSECT`; - //PipelineTemplateErrorLogger.logError(error); - throw error; - } - } - - private static _splitByOperator(id: string): any[] { - var operators: string[] = Object.keys(Operator).filter(k => typeof Operator[k as any] === "number" && k !== "UNDEFINED"); - var parts: string[] = []; - operators.forEach((operator: string) => { - var delimiter: string = " " + operator + " "; - if (id.indexOf(delimiter) !== -1) { - parts = id.split(delimiter); - parts[2] = Operator[operator as any]; - return; - } - }); - - if (parts.length === 0) { - return [id]; - } else { - return parts; - } - } - - private static _validateDataSourceId(dataSourceId: string): void { - var error: string; - if (!dataSourceId) { - error = "DataSourceId should not be null or empty"; - } - - var parts: string[] = dataSourceId.trim().split(" "); - if (parts.length > 1 && parts.length !== 3) { - error = "Invalid DataSourceId. It does not support multiple operators. It should be of format 'expression' or 'expression1 [OPERATOR] expression2'"; - } - - if (dataSourceId.startsWith('(') || dataSourceId.endsWith(')')) { - error = "Invalid DataSourceId. It should not start or end with braces"; - } - - if (error) { - //PipelineTemplateErrorLogger.logError(error); - throw new Error(error); - } - } -} - -export enum Operator { - UNDEFINED = 0, - INTERSECT = 1, - OR = 2 -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts deleted file mode 100644 index efaeea2f..00000000 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import { isNullOrUndefined } from 'util'; -import { ArmRestClient } from "../../clients/azure/armRestClient"; -import { MustacheHelper } from "../../helper/mustacheHelper"; -import { DataSource } from "../../model/Contracts"; -import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; - -export class DataSourceUtility { - - public static getDependentInputIdList(dataSourceEndpointUrl: string): string[] { - var inputIds: string[] = []; - if (!!dataSourceEndpointUrl) { - var dependentInputs = dataSourceEndpointUrl.match(/\{\{\{inputs.\w+\}\}\}/g); - if (!!dependentInputs) { - dependentInputs.forEach((value) => { - var startIndex = value.indexOf("{{{inputs.") + "{{{inputs.".length; - var endIndex = value.indexOf("}}}"); - var inputId = value.substring(startIndex, endIndex); - inputIds.push(inputId); - }); - } - } - - return inputIds; - } - - public static getDataSourceById(dataSources: Array, dataSourceId: string) { - for (var dataSource of dataSources) { - if (dataSource.id === dataSourceId) { - return dataSource; - } - } - return null; - } - - public static async evaluateDataSource(dataSource: DataSource, inputs: StringMap, azureSession: AzureSession): Promise { - - var view = { inputs: inputs }; - var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); - var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); - } - - private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { - if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); - response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); - if (response === "" || response === isNullOrUndefined) { - return null; - } - } - - if (Array.isArray(response)) { - var quickPickItems: Array = []; - - if (!!dataSource.resultTemplate) { - // Apply resultTemplate to each element in the Array - for (let item of response) { - if (typeof item === 'string' || item instanceof String) { - item = { "result": item }; - } - var resultObj = JSON.parse(MustacheHelper.render(dataSource.resultTemplate, { ...view, ...item })); - quickPickItems.push({ label: resultObj.DisplayValue, data: resultObj.Value }); - } - } - else { - for (let item of response) { - quickPickItems.push({ label: item, data: item }); - } - } - - return quickPickItems; - } - else { - if (!!dataSource.resultTemplate) { - response = MustacheHelper.render(dataSource.resultTemplate, { ...view, ...response }); - } - - return response; - } - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/InputControlUtility.ts b/src/configure/templateInputHelper/utilities/InputControlUtility.ts deleted file mode 100644 index f02c1e31..00000000 --- a/src/configure/templateInputHelper/utilities/InputControlUtility.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InputMode } from "../../model/Contracts"; -import { ControlType } from "../../model/models"; - -export class InputControlUtility { - - public static doesExpressionContainsDependency(expression: string): boolean { - if (!expression) { - return false; - } - - return /{{{inputs\.\w+}}}|{{{system\.\w+}}}|{{{client\.\w+}}}/g.test(expression); - } - - public static getDependentInputIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Input); - } - - public static getDependentClientIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.Client); - } - - public static getDependentSystemIdList(expression: string): string[] { - return this._fetchIdsInExpressionByType(expression, DependencyType.System); - } - - public static getInputControlType(inputMode: InputMode): ControlType { - switch (inputMode) { - case InputMode.None: - case InputMode.AzureSubscription: - return ControlType.None; - case InputMode.TextBox: - case InputMode.PasswordBox: - return ControlType.InputBox; - case InputMode.Combo: - case InputMode.CheckBox: - case InputMode.RadioButtons: - return ControlType.QuickPick; - default: - return null; - } - } - - private static _fetchIdsInExpressionByType(expression: string, dependencyType: DependencyType): string[] { - if (!expression) { - return []; - } - - var regex; - switch (dependencyType) { - case DependencyType.Input: - regex = /{{{inputs\.(\w+)}}}/g; - break; - - case DependencyType.System: - regex = /{{{system\.(\w+)}}}/g; - break; - - case DependencyType.Client: - regex = /{{{client\.(\w+)}}}/g; - break; - } - - var dependentIds: string[] = []; - var uniqueDependentIdMap = new Map(); - var resultArray; - while ((resultArray = regex.exec(expression)) !== null) { - uniqueDependentIdMap.set(resultArray[1], null); - } - - uniqueDependentIdMap.forEach((value, key) => { - dependentIds.push(key); - }); - return dependentIds; - } -} - -enum DependencyType { - Input, - System, - Client -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts b/src/configure/templateInputHelper/utilities/VisibilityHelper.ts deleted file mode 100644 index d403a8bd..00000000 --- a/src/configure/templateInputHelper/utilities/VisibilityHelper.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IPredicate, IVisibilityRule } from "../../model/models"; -import { InputControl } from "../InputControl"; - -const Operator_AND: string = "&&"; -const Operator_OR: string = "||"; - -export class VisibilityHelper { - public static parseVisibleRule(visibleRule: string): IVisibilityRule { - let rule: IVisibilityRule = null; - if (visibleRule) { - if (visibleRule.indexOf(Operator_AND) !== -1) { - let rules = visibleRule.split(Operator_AND); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_AND, - predicateRules: predicateRules - }; - } else if (visibleRule.indexOf(Operator_OR) !== -1) { - let rules = visibleRule.split(Operator_OR); - let predicateRules = rules.map(this.getPredicateRule); - rule = { - operator: Operator_OR, - predicateRules: predicateRules - }; - } else { - let predicateRule = this.getPredicateRule(visibleRule); - rule = { - operator: null, - predicateRules: [predicateRule] - }; - } - } - - return rule; - } - - public static evaluateVisibility(visibilityRule: IVisibilityRule, dependentInputs: InputControl[]): boolean { - let result: boolean = visibilityRule.operator === Operator_AND; - - for (let i = 0, len = visibilityRule.predicateRules.length; i < len; i++) { - let predicateRule = visibilityRule.predicateRules[i]; - let dependentInput: InputControl = dependentInputs.find((dependentInput: InputControl) => { - return dependentInput.getInputControlId() === predicateRule.inputName; - }); - - if (dependentInput) { - let isInputVisible = dependentInput.isVisible(); - if (!isInputVisible) { - result = this._evaluate(result, isInputVisible, visibilityRule.operator); - } else { - let predicateResult = this._getPredicateResult(predicateRule, dependentInput.getValue()); - result = this._evaluate(result, predicateResult, visibilityRule.operator); - } - } else { - result = false; - break; - } - } - return result; - } - - private static getPredicateRule(visibleRule: string): IPredicate { - let reg = /([a-zA-Z0-9 ]+)([!=<>]+)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=NotContains|NotEndsWith|NotStartsWith))(NotContains|NotEndsWith|NotStartsWith)([a-zA-Z0-9. ]+)|([a-zA-Z0-9 ]+(?=Contains|EndsWith|StartsWith))(Contains|EndsWith|StartsWith)([a-zA-Z0-9. ]+)/g; - let rule: IPredicate = null; - let matches = reg.exec(visibleRule); - if (matches && matches.length === 10) { - if (!!matches[1]) { - rule = { - inputName: matches[1].trim(), - condition: matches[2].trim(), - inputValue: matches[3].trim() - }; - } else if (!!matches[4]) { - rule = { - inputName: matches[4].trim(), - condition: matches[5].trim(), - inputValue: matches[6].trim() - }; - } else { - rule = { - inputName: matches[7].trim(), - condition: matches[8].trim(), - inputValue: matches[9].trim() - }; - } - } - return rule; - } - - private static _getPredicateResult(rule: IPredicate, valueToCheck: string): boolean { - let returnValue: boolean = false; - - let valueToCheckLowerCase = valueToCheck ? valueToCheck.toString().toLowerCase() : valueToCheck; - - if (rule) { - let expectedValue = rule.inputValue ? rule.inputValue.toString().toLowerCase() : rule.inputValue; - - switch (rule.condition) { - case "=": - case "==": - returnValue = (valueToCheckLowerCase === expectedValue); - break; - case "!=": - returnValue = (valueToCheckLowerCase !== expectedValue); - break; - case "<": - returnValue = (valueToCheckLowerCase < expectedValue); - break; - case ">": - returnValue = (valueToCheckLowerCase > expectedValue); - break; - case "<=": - returnValue = (valueToCheckLowerCase <= expectedValue); - break; - case ">=": - returnValue = (valueToCheckLowerCase >= expectedValue); - break; - case "Contains": - returnValue = (valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "StartsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "EndsWith": - returnValue = (valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - case "NotContains": - returnValue = !(valueToCheck && valueToCheck.indexOf(expectedValue) >= 0); - break; - case "NotStartsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().startsWith(expectedValue.toLowerCase())); - break; - case "NotEndsWith": - returnValue = !(valueToCheck && valueToCheck.toLowerCase().endsWith(expectedValue.toLowerCase())); - break; - } - } - - return returnValue; - } - - private static _evaluate(expr1: boolean, expr2: boolean, operator: string): boolean { - if (operator === Operator_AND) { - return expr1 && expr2; - } else if (operator === Operator_OR) { - return expr1 || expr2; - } else if (operator === null) { - // Single condition, no operator - return expr2; - } - return true; - } -} \ No newline at end of file diff --git a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts b/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts deleted file mode 100644 index d30f9dd0..00000000 --- a/src/configure/templateInputHelper/utilities/validation/StaticValidator.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as utils from 'util'; -import { Messages } from "../../../resources/messages"; - -export class StaticValidator { - public static validateRequired(value: string): any { - if (!value) { - return Messages.valueRequired; - } - return ""; - } - - public static validateLength(value: string, minLength: number, maxLength: number): any { - if (minLength && minLength > 0 && value.length < minLength) { - return utils.format(Messages.minLengthMessage, minLength); - } - else if (maxLength && maxLength > 0 && value.length > maxLength) { - return utils.format(Messages.maxLengthMessage, maxLength); - } - return ""; - } - - public static validateNumberValue(value: any, minValue: number, maxValue: number): any { - if (!isNaN(Number(value.toString()))) { - var intValue = parseInt(value); - if (minValue && intValue < minValue) { - return utils.format(Messages.minValueMessage, minValue); - } - else if (maxValue && intValue > maxValue) { - return utils.format(Messages.maxValueMessage, maxValue); - } - } - else { - return utils.format(Messages.valueShouldBeNumber, value.toString()); - } - return ""; - } - - public static validateRegex(value: string, pattern: string, regexFlags: string = ""): any { - var regex = new RegExp(pattern, regexFlags); - if (!regex.test(value)) { - return utils.format(Messages.regexPatternNotMatchingMessage, pattern); - } - return ""; - } -} \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml deleted file mode 100644 index 25ba5644..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxFunctionApp.yml +++ /dev/null @@ -1,78 +0,0 @@ -# .NET Core Function App to Linux on Azure -# Build a .NET Core function app and deploy it to Azure as a Linux function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/dotnet:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME dotnet' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml deleted file mode 100644 index c17c6f37..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreLinuxWebApp.yml +++ /dev/null @@ -1,108 +0,0 @@ -# .NET Core Web App to Linux on Azure -# Build a .NET Core Web App and deploy it to Azure as a Linux Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureRMWebAppDeployment@4 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - ConnectionType: "AzureRM" - ConnectedServiceName: $(azureSubscription) - WebAppName: $(webAppName) - WebAppKind: webAppLinux - Package: $(Pipeline.Workspace)/**/*.zip - DeploymentType: "webDeploy" - RuntimeStack: "DOTNETCORE|2.2" diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml deleted file mode 100644 index 7a244135..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsFunctionApp.yml +++ /dev/null @@ -1,76 +0,0 @@ -# .NET Core Function App to Windows on Azure -# Build a .NET Core function app and deploy it to Azure as a Windows function App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Function app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: "$(workingDirectory)/*.csproj" - arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Azure Functions App Deploy: {{ functionAppName }}' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml b/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml deleted file mode 100644 index ac28fd94..00000000 --- a/src/configure/templates/azurePipelineTemplates/dotnetcoreWindowsWebApp.yml +++ /dev/null @@ -1,105 +0,0 @@ -# .NET Core Web App to Windows on Azure -# Build a .NET Core Web App and deploy it to Azure as a Windows Web App. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web App name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Build Configuration - buildConfiguration: 'Release' - - # Build Projects - buildProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*.csproj' '$(workingDirectory)/**/*.csproj'{{/equals}}" - - # Test Projects - testProjects: "{{#equals}}{{{ workingDirectory }}} '.' true '**/*[Tt]est*/*.csproj' '$(workingDirectory)/**/*[Tt]est*/*.csproj'{{/equals}}" - - # Dotnet Core Version - dotnetCoreVersion: 2.x - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - version: $(dotnetCoreVersion) - - - task: DotNetCoreCLI@2 - displayName: Restore - inputs: - command: 'restore' - publishWebProjects: true - projects: $(buildProjects) - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: 'build' - projects: $(buildProjects) - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Test - inputs: - command: 'test' - projects: $(testProjects) - publishWebProjects: true - arguments: --configuration $(buildConfiguration) - - - task: DotNetCoreCLI@2 - displayName: Publish - inputs: - command: 'publish' - publishWebProjects: true - arguments: --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory) - zipAfterPublish: true - - - publish: $(Build.ArtifactStagingDirectory) - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(webAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/**/*.zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejs.yml b/src/configure/templates/azurePipelineTemplates/nodejs.yml deleted file mode 100644 index e85719f2..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejs.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js App on Windows Web App -# Build a Node.js app and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index c9eb0d40..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,86 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/node:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME node' diff --git a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml deleted file mode 100644 index c88c9899..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js App on Linux Web App -# Build a Node.js app and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - npm build - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 34911c21..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'vs2017-win2016' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - powershell: | - if (Test-Path "extensions.csproj") { - dotnet build extensions.csproj --output ./bin - } - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - script: | - npm install - npm run build --if-present - npm run test --if-present - displayName: 'Prepare binaries' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - strategy: - runOnce: - deploy: - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionApp - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml deleted file mode 100644 index fb084fbc..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngular.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml deleted file mode 100644 index 10238ccb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithAngularLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g @angular/cli - npm install - ng build --prod - displayName: 'npm install and build' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml deleted file mode 100644 index d3b144eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGrunt.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml deleted file mode 100644 index b6c61d9e..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGruntLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - grunt --gruntfile Gruntfile.js - displayName: 'npm install and run grunt' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml deleted file mode 100644 index 19e22a8f..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulp.yml +++ /dev/null @@ -1,72 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml deleted file mode 100644 index bd3208eb..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithGulpLinuxWebApp.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install - gulp default --gulpfile gulpfile.js - displayName: 'npm install and run gulp' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml deleted file mode 100644 index f7d6f4a3..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpack.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml deleted file mode 100644 index 9b549b2b..00000000 --- a/src/configure/templates/azurePipelineTemplates/nodejsWithWebpackLinuxWebApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '10.x' - displayName: 'Install Node.js' - - - script: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - displayName: 'npm install, run webpack' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - runtimeStack: 'NODE|10.10' - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml b/src/configure/templates/azurePipelineTemplates/pythonDjango.yml deleted file mode 100644 index 061f3174..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonDjango.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Python Django -# Test a Django project on multiple versions of Python. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python35: - PYTHON_VERSION: '3.5' - Python36: - PYTHON_VERSION: '3.6' - Python37: - PYTHON_VERSION: '3.7' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt - pip install unittest-xml-reporting - displayName: 'Install prerequisites' - -- script: | - pushd '$(projectRoot)' - python manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - displayName: 'Run tests' - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index de511c74..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - functionAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - - # Python Version - pythonVersion: 3.6 # Functions V2 supports Python 3.6 as of today - -stages: -- stage: Build - displayName: Build stage - - jobs: - - job: Build - displayName: Build - pool: - vmImage: $(vmImageName) - - steps: - - bash: | - if [ -f extensions.csproj ] - then - dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin - fi - displayName: 'Build extensions' - workingDirectory: $(workingDirectory) - - - task: UsePythonVersion@0 - displayName: 'Use Python 3.6' - inputs: - versionSpec: $(pythonVersion) - - - bash: | - python -m venv worker_venv - source worker_venv/bin/activate - pip install -r requirements.txt - displayName: 'Install application dependencies' - workingDirectory: $(workingDirectory) - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(workingDirectory)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - - jobs: - - deployment: Deploy - displayName: Deploy - environment: $(functionAppName) - pool: - vmImage: $(vmImageName) - - strategy: - runOnce: - deploy: - - steps: - - task: AzureFunctionApp@1 - displayName: 'Deploy Azure Functions App: $(functionAppName)' - inputs: - azureSubscription: '$(azureSubscription)' - appType: functionAppLinux - appName: $(functionAppName) - package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' - runtimeStack: 'DOCKER|microsoft/azure-functions/python:2.0' - appSettings: '-FUNCTIONS_WORKER_RUNTIME python' \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index b6466457..00000000 --- a/src/configure/templates/azurePipelineTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Python to Linux Web App on Azure -# Build your Python project and deploy it to Azure as a Linux Web App. -# Change python version to one thats appropriate for your application. -# https://docs.microsoft.com/azure/devops/pipelines/languages/python - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection created during pipeline creation - azureServiceConnectionId: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Agent VM image name - vmImageName: 'ubuntu-latest' - - # Environment name - environmentName: '{{{ targetResource.resource.name }}}' - - # Project root folder. Point to the folder containing manage.py file. - projectRoot: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - pool: - vmImage: $(vmImageName) - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - script: | - python -m venv --copies antenv - source antenv/bin/activate - python -m pip install --upgrade pip - pip install setup - pip install -r requirements.txt - workingDirectory: $(projectRoot) - displayName: "Install requirements" - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: '$(projectRoot)' - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - displayName: 'Upload package' - artifact: drop - -- stage: Deploy - displayName: 'Deploy Web App' - dependsOn: Build - condition: succeeded() - jobs: - - deployment: DeploymentJob - pool: - vmImage: $(vmImageName) - environment: $(environmentName) - strategy: - runOnce: - deploy: - steps: - - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - displayName: 'Use Python 3.7' - - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureServiceConnectionId) - appName: $(webAppName) - appType: webAppLinux - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - runtimeStack: 'PYTHON|3.7' - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images \ No newline at end of file diff --git a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml deleted file mode 100644 index 514e52b0..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleLinuxWebApp.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Simple App on Linux Web App -# Package and deploy a simple web application and deploy it to Azure as Linux web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'ubuntu-latest' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'ubuntu-latest' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webAppLinux - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip - startupCommand: '' # Provide an optional startup command that will be run as part of container startup. For Node, it is the PM2 configuration file or your script file; For .Net Core it is the compiled DLL name as dotnet .dll. Learn more at https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#built-in-images diff --git a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml b/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml deleted file mode 100644 index 1ea8f197..00000000 --- a/src/configure/templates/azurePipelineTemplates/simpleWebApp.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Simple App on Windows Web App -# Package and deploy a simple web application and deploy it to Azure as Windows web app. - -trigger: -- {{{ sourceRepository.branch }}} - -variables: - # Azure Resource Manager connection - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' - - # Web app name - webAppName: '{{{ targetResource.resource.name }}}' - - # Working Directory - workingDirectory: '{{{ workingDirectory }}}' - -stages: -- stage: Build - displayName: Build stage - jobs: - - job: BuildJob - displayName: Build - pool: - vmImage: 'vs2017-win2016' - - steps: - - - task: ArchiveFiles@2 - displayName: 'Archive files' - inputs: - rootFolderOrFile: $(workingDirectory) - includeRootFolder: false - archiveType: zip - archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - replaceExistingArchive: true - - - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip - artifact: drop - -- stage: Deploy - displayName: Deploy stage - dependsOn: Build - condition: succeeded() - jobs: - - deployment: Deploy - environment: 'development' - pool: - vmImage: 'vs2017-win2016' - - strategy: - runOnce: - deploy: - steps: - - task: AzureWebApp@1 - displayName: 'Deploy Azure Web App: $(webAppName)' - inputs: - azureSubscription: $(azureSubscription) - appType: webApp - appName: $(webAppName) - package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip diff --git a/src/configure/templates/dependencies/deployment.yml b/src/configure/templates/dependencies/deployment.yml deleted file mode 100644 index 315a775c..00000000 --- a/src/configure/templates/dependencies/deployment.yml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion : apps/v1 -kind: Deployment -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - replicas: 2 - selector: - matchLabels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - template: - metadata: - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - spec: - containers: - - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - image: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io/{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - ports: - - containerPort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/ingress.yml b/src/configure/templates/dependencies/ingress.yml deleted file mode 100644 index da5ceaf0..00000000 --- a/src/configure/templates/dependencies/ingress.yml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - annotations: - kubernetes.io/ingress.class: addon-http-application-routing -spec: - rules: - - host: {{{ inputs.namespace }}}-{{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}}.{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.config.httpapplicationroutingzonename }}} - http: - paths: - - path: / - backend: - serviceName: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - servicePort: {{{ inputs.containerPort }}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service-ingress.yml b/src/configure/templates/dependencies/service-ingress.yml deleted file mode 100644 index 5649f801..00000000 --- a/src/configure/templates/dependencies/service-ingress.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: ClusterIP - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/dependencies/service.yml b/src/configure/templates/dependencies/service.yml deleted file mode 100644 index 8627a516..00000000 --- a/src/configure/templates/dependencies/service.yml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - labels: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} -spec: - type: LoadBalancer - ports: - - port: {{{ inputs.containerPort }}} - targetPort: {{{ inputs.containerPort }}} - protocol: TCP - name: http - selector: - app: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml b/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml deleted file mode 100644 index b63cb8bd..00000000 --- a/src/configure/templates/githubWorkflowTemplates/AksWithReuseACR.yml +++ /dev/null @@ -1,62 +0,0 @@ -on: [push] -jobs: - build-and-deploy: - env: - REGISTRY_URL: {{#toLower}}{{{inputs.containerRegistry.name}}}{{/toLower}}.azurecr.io - NAMESPACE: {{{ inputs.namespace }}} - IMAGE_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 50{{/substring}} - SECRET_NAME: {{#substring}}'{{#toLower}}{{#sanitizeString}}{{{ inputs.aksCluster.name }}}{{/sanitizeString}}{{/toLower}}' 0 63{{/substring}} - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - - uses: azure/docker-login@v1 - with: - {{=<% %>=}} - login-server: ${{ env.REGISTRY_URL }} - username: ${{ secrets.<% assets.containerRegistryUsername %> }} - password: ${{ secrets.<% assets.containerRegistryPassword %> }} - <%={{ }}=%> - - - name: Build and push image to ACR - id: build-image - run: | - docker build "$GITHUB_WORKSPACE/{{{ workingDirectory }}}" -f "{{{ workingDirectory }}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ github.sha }}<%={{ }}=%> - - - uses: azure/k8s-set-context@v1 - with: - kubeconfig: {{=<% %>=}}${{ secrets.<% assets.kubeConfig %> }}<%={{ }}=%> - id: login - - - name: Create namespace - run: | - namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` - if [ $namespacePresent -eq 0 ] - then - echo `kubectl create namespace $NAMESPACE` - fi - - - uses: azure/k8s-create-secret@v1 - with: - {{=<% %>=}} - namespace: ${{ env.NAMESPACE }} - container-registry-url: ${{ env.REGISTRY_URL }} - container-registry-username: ${{ secrets.<% assets.containerRegistryUsername %> }} - container-registry-password: ${{ secrets.<% assets.containerRegistryPassword %> }} - secret-name: ${{ env.SECRET_NAME }} - <%={{ }}=%> - - - uses: azure/k8s-deploy@v1 - with: - namespace: {{=<% %>=}}${{ env.NAMESPACE }}<%={{ }}=%> - manifests: | - {{{assets.deployment}}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.service-ingress}}} {{{assets.service}}} {{/if}} - {{#if}}{{{inputs.aksCluster.properties.addonProfiles.httpApplicationRouting.enabled}}} {{{assets.ingress}}} {{/if}} - - images: | - {{=<% %>=}}${{ env.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ github.sha }}<%={{ }}=%> - imagepullsecrets: | - {{=<% %>=}}${{ env.SECRET_NAME }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml deleted file mode 100644 index bd4b40be..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsLinuxFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Linux on Azure -# Build a Node.js function app and deploy it to Azure as a Linux function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml deleted file mode 100644 index c096f37c..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnLinux.yml +++ /dev/null @@ -1,42 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|lts"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml b/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml deleted file mode 100644 index 1389a176..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsOnWindows.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build, and test - working-directory: {{{ workingDirectory }}} - run: | - npm install - npm run build --if-present - npm run test --if-present - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml deleted file mode 100644 index 72bc146f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWindowsFunctionApp.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Node.js Function App to Windows on Azure -# Build a Node.js function app and deploy it to Azure as a Windows function app. -# Add steps that build code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node Function app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - name: 'Run npm' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - # If your function app project is not located in your repository's root - # Please change your directory for npm in pushd - pushd . - npm install - npm run build --if-present - npm run test --if-present - popd - - # deploy web app using publish profile credentials - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml deleted file mode 100644 index f872c4ab..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with Angular on Linux Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml deleted file mode 100644 index 432bf6c7..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithAngularOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with Angular on Windows Web App -# Build a Node.js project that uses Angular and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g @angular/cli - npm install - ng build --prod - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml deleted file mode 100644 index 11242a00..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with Grunt on Linux Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml deleted file mode 100644 index e9b77f9f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGruntOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with Grunt on Windows Web App -# Build a Node.js project using the Grunt task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - grunt --gruntfile {{{repositoryAnalysisApplicationSettings.settings.gruntFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml deleted file mode 100644 index 15e7b975..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnLinuxWebApp.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Node.js with gulp on Linux Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml deleted file mode 100644 index 55417b2d..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithGulpOnWindowsWebApp.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Node.js with gulp on Windows Web App -# Build a Node.js project using the gulp task runner and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install - gulp default --gulpfile {{{repositoryAnalysisApplicationSettings.settings.gulpFilePath}}} - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml deleted file mode 100644 index db5f637f..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnLinuxWebApp.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Node.js with webpack on Linux Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Linux web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # login using publishing credentials - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "NODE|10.10"}' #'General configuration settings as Key Value pairs' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml b/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml deleted file mode 100644 index 006c3cfb..00000000 --- a/src/configure/templates/githubWorkflowTemplates/nodejsWithWebpackOnWindowsWebApp.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Node.js with webpack on Windows Web App -# Build a Node.js project using the webpack CLI and deploy it to Azure as a Windows web app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Node app - -jobs: - build-and-deploy: - runs-on: windows-2019 - steps: - # checkout the repo - - uses: actions/checkout@master - - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - # install dependencies, build, and test - - name: npm install, build - working-directory: {{{ workingDirectory }}} - run: | - npm install -g webpack webpack-cli --save-dev - npm install - npx webpack --config webpack.config.js - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml deleted file mode 100644 index f9189261..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxFunctionApp.yml +++ /dev/null @@ -1,74 +0,0 @@ -# Python Function App to Linux on Azure -# Build a Python function app and deploy it to Azure as a Linux function app. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python Function app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # Setup python - - name: Setup python - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - # Install dependencies - - name: 'Run pip' - shell: bash - working-directory: {{{ workingDirectory }}} - run: | - python -m pip install --upgrade pip - python -m venv --copies worker_venv - source worker_venv/bin/activate - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - # deploy function - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - scm-do-build-during-deployment: true - enable-oryx-build: true - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml b/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml deleted file mode 100644 index 9a7f4803..00000000 --- a/src/configure/templates/githubWorkflowTemplates/pythonLinuxWebApp.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Python Web App to Linux on Azure -# Build a Python WebApp and deploy it to Azure as a Linux WebApp. -# Add steps that analyze code, save build artifacts, deploy, and more: - -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Build and deploy Python app - -jobs: - build: - runs-on: ubuntu-latest - steps: - - # checkout the repo - - uses: actions/checkout@master - - # setup python - - name: Setup Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - # install dependencies - - name: python install - working-directory: {{{ workingDirectory }}} - run: | - sudo apt install python3.7-venv - python -m venv --copies antenv - source antenv/bin/activate - pip install setuptools - pip install -r {{{repositoryAnalysisApplicationSettings.settings.pythonRequirementsFilePath}}} - - # Upload artificats - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v2 - with: - name: webapp - path: | - . - !venv/ - - deploy: - runs-on: ubuntu-latest - needs: build - steps: - - # Download artifacts - - name: Download artifact from build job - uses: actions/download-artifact@v2 - with: - name: webapp - path: . - - # Azure login - - uses: azure/login@v1 - with: - creds: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> - - - uses: azure/appservice-settings@v1 - with: - app-name: {{{ targetResource.resource.name }}} - general-settings-json: '{"linuxFxVersion": "PYTHON|3.7"}' #'General configuration settings as Key Value pairs' - app-settings-json: '[{ "name": "SCM_DO_BUILD_DURING_DEPLOYMENT", "value": "true" }]' - - # deploy web app - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - - # Azure logout - - name: logout - run: | - az logout \ No newline at end of file diff --git a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml b/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml deleted file mode 100644 index 0254cfac..00000000 --- a/src/configure/templates/githubWorkflowTemplates/simpleWebApp.yml +++ /dev/null @@ -1,20 +0,0 @@ -on: - push: - branches: - - {{{ sourceRepository.branch }}} - -name: Package and deploy simple web app - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - # checkout the repo - - uses: actions/checkout@master - - # deploy web app using publish profile credentials - - uses: azure/webapps-deploy@v1 - with: - app-name: {{{ targetResource.resource.name }}} - package: {{{ workingDirectory }}} - publish-profile: {{=<% %>=}}${{ secrets.<% targetResource.serviceConnectionId %> }}<%={{ }}=%> \ No newline at end of file diff --git a/src/configure/test/index.ts b/src/configure/test/index.ts deleted file mode 100644 index cc6ffb47..00000000 --- a/src/configure/test/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as glob from 'glob'; -import * as Mocha from 'mocha'; -import * as path from 'path'; - -export function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true - }); - - const testsRoot = path.resolve(__dirname, '..'); - - return new Promise((c, e) => { - glob('**/suite/**.test.js', { cwd: testsRoot }, (err, files) => { - if (err) { - return e(err); - } - - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); - - try { - // Run the mocha test - mocha.run(failures => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } - }); - } catch (err) { - console.error(err); - e(err); - } - }); - }); -} diff --git a/src/configure/test/runTest.ts b/src/configure/test/runTest.ts deleted file mode 100644 index 0bdd6b8a..00000000 --- a/src/configure/test/runTest.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import { runTests } from 'vscode-test'; - - -async function testHost() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); - - // The path to test runner - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './index'); - - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); - } catch (err) { - console.error('Failed to run tests. Error : ' + err); - process.exit(1); - } -} - -testHost(); diff --git a/src/configure/test/suite/GitHubClient.test.ts b/src/configure/test/suite/GitHubClient.test.ts deleted file mode 100644 index b0fcd2d0..00000000 --- a/src/configure/test/suite/GitHubClient.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let repoName = "Repository"; -let githubClient = new GithubClient("PAT", "repoUrl"); - -var orgList = [ - { - "login": "SampleOrganizationA", - "id": 66720950, - "url": "https://api.github.com/orgs/SampleOrganizationA", - "repos_url": "https://api.github.com/orgs/SampleOrganizationA/repos" - }, - { - "login": "SampleOrganizationB", - "id": 67440137, - "url": "https://api.github.com/orgs/SampleOrganizationB", - "repos_url": "https://api.github.com/orgs/SampleOrganizationB/repos", - }, - { - "login": "SampleOrganizationC", - "id": 67453753, - "url": "https://api.github.com/orgs/SampleOrganizationC", - "repos_url": "https://api.github.com/orgs/SampleOrganizationC/repos" - }]; - -var repoCreationResponseOnSuccess = { - "id": 278008782, - "name": repoName, - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -var repoCreationResponseOnFailure = { - "message": "Resource protected by organization SAML enforcement. You must grant your PAT access to this organization", - "documentation_url": "some url" -}; - -describe('# Testing listOrganizations() ', function () { - - context('User is a member of organizations(s)', function () { - it('should return a list of organizations', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, orgList); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(3); - orgs.forEach((org) => { - expect(org).to.have.property('login'); - expect(org).to.have.property('id'); - expect(org).to.have.property('url'); - }); - done(); - }); - }); - }); - - context('User is not a member of any organization', function () { - it('Should return an empty list of organization', function (done) { - nock('https://api.github.com') - .get('/user/orgs') - .reply(200, []); - githubClient.listOrganizations(true).then((orgs) => { - expect(Array.isArray(orgs)).to.equal(true); - expect(orgs.length).to.equal(0); - done(); - }); - }); - }); -}); - -describe('# Testing createGitHubRepo()', function () { - - context('Given repository name is unique', function () { - it('Should create a new repository', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, repoCreationResponseOnSuccess); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to existence of repository of same name within the organization', function () { - it('Should return null', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(422, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then((repo) => { - expect(repo).to.equal(null); - done(); - }); - }); - }); - - context('Repository creation fails due to some other reason', function () { - it('Should throw error', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos') - .reply(400, repoCreationResponseOnFailure); - githubClient.createGithubRepo(org, repoName).then(function () { - done(); - }).catch(err => { - expect(err).to.equal(err); - done(); - }); - }) - }); - -}); diff --git a/src/configure/test/suite/commonHelper.test.ts b/src/configure/test/suite/commonHelper.test.ts deleted file mode 100644 index 210c8d4b..00000000 --- a/src/configure/test/suite/commonHelper.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { GithubClient } from "../../clients/github/githubClient"; -import { generateGitHubRepository } from "../../helper/commonHelper"; - -var expect = require('chai').expect; -var nock = require('nock'); - -let org = "Organization"; -let localPath = "c:/directory/Repository"; -let githubClient = new GithubClient("PAT", localPath); -let repoName = "Repository"; - -var responseOnFailure = { - "message": "Repository creation failed.", - "errors": [ - { - "resource": "Repository", - "code": "custom", - "field": "name", - "message": "name already exists on this account" - } - ], -}; - -var responseOnSuccess = { - "id": 278008782, - "name": "Some repo name", - "private": true, - "owner": { - "login": org, - "id": 67440137 - }, - "html_url": "https://github.com/" + org + "/" + repoName, - "description": "Repo created from VScode extension 'Deploy to Azure'" -}; - -describe('# Testing generateGithubRepository()', function () { - - context('Local repository name is unique inside selected organization', function () { - it('Should create a new repository with the same name as local repository name', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository', function () { - it('Should create a new repository with the name = "local name + org name"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); - - context('Selected organization contains a repository with same name as local repository and another repository with the name - "Local repository name + Organization Name"', function () { - it('Should create a new repository with the name = "local name + org name + uuid"', function (done) { - nock('https://api.github.com') - .post('/orgs/' + org + '/repos', _.matches({ name: repoName })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', _.matches({ name: repoName + "_" + org })) - .reply(422, responseOnFailure) - .post('/orgs/' + org + '/repos', body => /Repository_Organization_[a-zA-Z0-9]*/.test(body.name)) - .reply(200, responseOnSuccess); - generateGitHubRepository(org, localPath, githubClient).then((repo) => { - expect(repo).to.not.deep.equal(null); - done(); - }); - }); - }); -}); \ No newline at end of file diff --git a/src/configure/utilities/templateConverter.ts b/src/configure/utilities/templateConverter.ts deleted file mode 100644 index 9aee4281..00000000 --- a/src/configure/utilities/templateConverter.ts +++ /dev/null @@ -1,108 +0,0 @@ -const parametersRegex = /(inputs|variables|assets|secrets|system)\.\w+/g; -const enclosedParametersRegex = /{{{?\s*(inputs|variables|assets|secrets|system)\.\w+\s*}?}}/g; -const mustacheHelperRegex = /{{{?\s*#(\w+)(.*?)({?{{\s*\/\1)}?}}/; - -export function convertExpression(expression: string): string { - let match = expression.match(mustacheHelperRegex); - if (!match) { - return expression; - } - let localMustacheExpression = ""; - let openingHelperFunc = "{{"; - let closingHelperFunc = "}}"; - let parts = []; - let helperName = ""; - - if (expression.startsWith('{{{')) { - closingHelperFunc = "}}}" - openingHelperFunc = "{{{" - } - - if (expression.indexOf(' ') !== -1 && expression.indexOf(' ') < expression.indexOf(closingHelperFunc)) { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(' ')); - parts.push(expression.substring(0, expression.indexOf(' ')) + closingHelperFunc); - let part = expression.substring(expression.indexOf(' '), expression.indexOf(closingHelperFunc)).trim(); - let input = parametersRegex.exec(part); - while (input) { - part = replaceAtIndex(part, input[0], "{{{" + input[0] + "}}}", input.index); - input = parametersRegex.exec(part); - } - parts.push(part); - } - else { - helperName = expression.substring(openingHelperFunc.length + 1, expression.indexOf(closingHelperFunc)); - parts.push(expression.substring(0, expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - - if (expression.substr(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, openingHelperFunc.length + 1 + helperName.length) === openingHelperFunc + '/' + helperName) { - parts.push(expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length)); - } - else { - let part = expression.substring(expression.indexOf(closingHelperFunc) + closingHelperFunc.length, expression.indexOf(openingHelperFunc + '/' + helperName)); - part = convertStringMustachExpression(part); - parts.push(part); - parts.push(expression.substring(expression.indexOf(openingHelperFunc + '/' + helperName))); - } - - if (parts.length === 4) { - localMustacheExpression = parts[0] + parts[1] + ' ' + parts[2] + parts[3]; - } - else { - localMustacheExpression = parts.join(''); - } - return localMustacheExpression - -} - -export function convertStringMustachExpression(text: string): string { - let helperRegExp = /{?{{\s*#(\w+)(.*?)({?{{\s*\/\1)}}}?/g; - let result = helperRegExp.exec(text); - while (result) { - let exp = convertExpression(result[0]); - text = replaceAtIndex(text, result[0], exp, result.index); - result = helperRegExp.exec(text); - } - return text; -} - -export function sanitizeExpression(text: string): string { - let result = enclosedParametersRegex.exec(text); - while (result) { - if (!result[0].startsWith('{{{')) { - text = replaceAtIndex(text, result[0], '{' + result[0] + '}', result.index); - } - result = enclosedParametersRegex.exec(text); - } - return text; -} - -export function convertToLocalMustacheExpression(object: any): any { - if (typeof object === "string") { - object = sanitizeExpression(object); - return convertStringMustachExpression(object); - } - - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - object[i] = convertToLocalMustacheExpression(object[i]); - } - return object; - } - - Object.keys(object).forEach(key => { - if (!!key && !!object[key]) { - object[key] = convertToLocalMustacheExpression(object[key]); - } - }); - - return object; -} - -function replaceAtIndex(text: string, searchValue: string, replaceValue: string, index: number) { - if (text.indexOf(searchValue, index) !== -1) { - let preStr = text.substr(0, index); - let postStr = text.substr(index + searchValue.length); - text = preStr + replaceValue + postStr; - } - return text; -} diff --git a/src/configure/utilities/utilities.ts b/src/configure/utilities/utilities.ts deleted file mode 100644 index 686c32f7..00000000 --- a/src/configure/utilities/utilities.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as crypto from 'crypto'; - -export class Utilities { - public static createSha256Hash(input: string): string { - return crypto.createHash('sha256').update(input).digest('hex'); - } -} - -export class WhiteListedError extends Error { - constructor(message?: string, error?: any) { - super(message || error.message); - if (error) { - const errorClone = JSON.parse(JSON.stringify(error)); - for (var attribute in errorClone) { - this[attribute] = errorClone[attribute]; - } - this.message = message || this.message; - this.stack = error.stack || ""; - } - } -} \ No newline at end of file diff --git a/src/configure/utilities/webAppNodeVersionConverter.ts b/src/configure/utilities/webAppNodeVersionConverter.ts deleted file mode 100644 index f475e577..00000000 --- a/src/configure/utilities/webAppNodeVersionConverter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { JSONPath } from 'jsonpath-plus'; -import * as vscode from 'vscode'; -import { ArmRestClient } from '../clients/azure/armRestClient'; -import { AzureSession } from "../model/models"; -import { Messages } from '../resources/messages'; - -export async function webAppRuntimeNodeVersionConverter(nodeVersion: string, armUri: string, azureSession: AzureSession): Promise { - if (nodeVersion.indexOf('|') >= 0) { - nodeVersion = nodeVersion.split('|')[1]; - } else { - nodeVersion = 'lts'; - } - if (nodeVersion.toLowerCase() === 'lts') { - let versions: string[]; - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: Messages.GettingNodeVersion - }, - async () => { - const resultSelector = "$.value[?(@.name === 'node')].properties.majorVersions[*].runtimeVersion"; - const response = await new ArmRestClient(azureSession).fetchArmData(armUri, 'GET'); - versions = JSONPath({ path: resultSelector, json: response, wrap: false, flatten: true }); - } - ); - let maxVersion = 0; - versions.forEach((version: string) => { - const match = version.match(/(\d+)(-lts|\.\d+)/i); - if (match && match.length > 1) { - maxVersion = Math.max(maxVersion, +match[1]); - } - }); - nodeVersion = maxVersion + '.x'; - } else if (nodeVersion.match(/(\d+)-lts/i)) { - nodeVersion = nodeVersion.replace(/-lts/i, '.x'); - } - return nodeVersion; -} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts deleted file mode 100644 index 56ed3cb5..00000000 --- a/src/extension.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -import * as path from 'path'; -import * as vscode from 'vscode'; -import { AzureUserInput, callWithTelemetryAndErrorHandling, createTelemetryReporter, IActionContext, registerUIExtensionVariables } from 'vscode-azureextensionui'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { activateConfigurePipeline } from './configure/activate'; -import { telemetryHelper } from './configure/helper/telemetryHelper'; -import { extensionVariables } from './configure/model/models'; -import { TelemetryKeys } from './configure/resources/telemetryKeys'; -import { TracePoints } from './configure/resources/tracePoints'; -import * as logger from './logger'; - -const Layer = 'Extension'; - -export async function activate(context: vscode.ExtensionContext) { - extensionVariables.reporter = createTelemetryReporter(context); - registerUiVariables(context); - - await callWithTelemetryAndErrorHandling('azuredeploy.activate', async (activateContext: IActionContext) => { - activateContext.telemetry.properties.isActivationEvent = 'true'; - telemetryHelper.initialize(activateContext, 'activate'); - await telemetryHelper.executeFunctionWithTimeTelemetry( - async () => { - await activateConfigurePipeline(); - }, - TelemetryKeys.ExtensionActivationDuration); - }); - - startLanguageClient(context); - - logger.log('Extension has been activated!', 'ExtensionActivated'); -} - -function startLanguageClient(context: vscode.ExtensionContext) { - try { - // The YAML language server is implemented in node - let serverModule = context.asAbsolutePath(path.join('node_modules', 'yaml-language-server', 'out', 'server', 'src', 'server.js')); - - // The debug options for the server - let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; - - // If the extension is launched in debug mode then the debug server options are used - // Otherwise the run options are used - let serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - - // Options to control the scope of language client - let clientOptions: LanguageClientOptions = { - documentSelector: [ - { language: "yaml", pattern: "**/.github/workflows/**", scheme: "file" } - ], - synchronize: { - // Synchronize these setting sections with the server - configurationSection: ['yaml', 'http.proxy', 'http.proxyStrictSSL'], - // Notify the server about file changes to YAML files contained in the workspace - fileEvents: [ - vscode.workspace.createFileSystemWatcher('**/*.?(e)y?(a)ml') - ] - } - }; - - // Create the language client and start it - let client = new LanguageClient('yaml', 'YAML Support', serverOptions, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - } - catch (error) { - telemetryHelper.logError(Layer, TracePoints.LanguageClientActivationFailed, error); - } -} - -function registerUiVariables(context: vscode.ExtensionContext) { - // Register ui extension variables is required to be done for telemetry to start flowing for extension activation and other events. - // It also facilitates registering command and called events telemetry. - extensionVariables.outputChannel = vscode.window.createOutputChannel('Deploy to Azure'); - context.subscriptions.push(extensionVariables.outputChannel); - extensionVariables.context = context; - extensionVariables.ui = new AzureUserInput(context.globalState); - registerUIExtensionVariables(extensionVariables); -} - -// this method is called when your extension is deactivated -export function deactivate() { -} \ No newline at end of file diff --git a/src/logger.ts b/src/logger.ts deleted file mode 100644 index 28a70627..00000000 --- a/src/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { extensionVariables } from "./configure/model/models"; - -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. -*--------------------------------------------------------------------------------------------*/ - -// TODO: How can we write this to disk too so that we can remotely debug issues? -// TODO: Set env var or something to turn logging on/off? - -export function log(message: string, event?: string){ - let logMessage = `(${new Date().toLocaleString()}) `; - - if (event) { - logMessage += `[${event}] `; - } - - logMessage += `${message}`; - extensionVariables.outputChannel.appendLine(logMessage); -} From 1dd2a99d6efc62ceae18c5610f9f6448a184445c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 00:02:54 +0000 Subject: [PATCH 96/96] Bump node-fetch from 2.6.0 to 2.7.0 in /.azure-pipelines/github-release Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.0...v2.7.0) --- updated-dependencies: - dependency-name: node-fetch dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .../github-release/package-lock.json | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/github-release/package-lock.json b/.azure-pipelines/github-release/package-lock.json index cce73f04..ea3ae52b 100644 --- a/.azure-pipelines/github-release/package-lock.json +++ b/.azure-pipelines/github-release/package-lock.json @@ -165,9 +165,12 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "npm-run-path": { "version": "2.0.2", @@ -241,6 +244,11 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "universal-user-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", @@ -254,6 +262,20 @@ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",

  • 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≶UIG#2~F_>~R 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